2012-02-24 15 views
16

Estoy intentando cargar algunos datos en una colección Backbone de un archivo JSON local, utilizando este código muy básico:¿Cargar datos en una colección Backbone del archivo JSON?

window.Student = Backbone.Model.extend({ 
    }); 
    window.Students = Backbone.Collection.extend({ 
    model: Student, 
    }); 
    window.AllStudents = new Students(); 
    AllStudents.fetch({ url: "/init.json"}); 
    console.log('AllStudents', AllStudents); 

En el comunicado consola, AllStudents está vacía. Pero init.json definitivamente se está cargando. Se ve así:

[ 
    { text: "Amy", grade: 5 }, 
    { text: "Angeline", grade: 26 }, 
    { text: "Anna", grade: 55 }  
] 

¿Qué estoy haciendo mal?

ACTUALIZACIÓN: También he intentado añadir un oyente reset encima de la llamada .fetch(), pero eso no es disparar ya sea:

AllStudents.bind("reset", function() { 
    alert('hello world'); 
}); 
AllStudents.fetch({ url: "/init.json"}); 

No aparece ninguna alerta

.

ACTUALIZACIÓN 2: Tratando este script (que se reproduce aquí en su totalidad): aparece

$(function(){ 
    window.Student = Backbone.Model.extend({ 
    }); 
    window.Students = Backbone.Collection.extend({ 
    model: Student, 
    }); 
    window.AllStudents = new Students(); 
    AllStudents.url = "/init.json"; 
    AllStudents.bind('reset', function() { 
     console.log('hello world'); 
    }); 
    AllStudents.fetch(); 
    AllStudents.fetch({ url: "/init.json", success: function() { 
     console.log(AllStudents); 
    }}); 
    AllStudents.fetch({ url: "/init.json" }).complete(function() { 
     console.log(AllStudents); 
    }); 
}); 

Sólo un comunicado consola, incluso, en el tercer fetch() llamada, y es un objeto vacío.

Ahora estoy absolutamente desconcertado. ¿Qué estoy haciendo mal?

El archivo JSON se sirve como application/json, por lo que no tiene nada que ver con eso.

+1

Es una buena pregunta. deberías haber usado http://jsonlint.com/ para verificar tu JSON –

Respuesta

0

creo que es necesario agregar {add:true} a las opciones de búsqueda,

si asignó la zona de alcance de una variable, que se obtiene el resultado, así, pero entonces no es dentro de la colección que quería

+0

No creo que sea correcto - '{add: true}' agrega, en lugar de reemplazar, los contenidos, pero quiero reemplazar los contenidos. – Richard

10

Las operaciones de E/S en javascript son casi siempre asincrónicas, y lo mismo ocurre con Backbone. Eso significa que simplemente porque AllStudents.fetch ha regresado, aún no ha recuperado los datos. Por lo tanto, cuando acierte a su declaración console.log, los recursos aún no se han recuperado. Debe pasar una devolución de llamada a fetch:

AllStudents.fetch({ url: "/init.json", success: function() { 
    console.log(AllStudents); 
}}); 

u opcionalmente, usar la nueva característica promesa en jQuery (fetch devolverá una promesa):

AllStudents.fetch({ url: "/init.json" }).complete(function() { 
    console.log(AllStudents); 
}); 
+0

Hm: esa declaración de consola nunca aparece, como si el éxito nunca se disparara. Sin embargo, el archivo 'init.json' definitivamente se está cargando ... – Richard

1

fetch() devuelve una notificación de 'éxito' como ya indicado, pero eso solo significa que la solicitud del servidor fue exitosa. fetch() trajo un poco de JSON, pero aún necesita rellenarlo en la colección.

La colección activa un evento de "restablecimiento" cuando se han actualizado sus contenidos. Es entonces cuando la colección está lista para usar ...

AllStudents.bind('reset', function() { alert('AllStudents bind event fired.'); }); 

Parece que tenía esto en su primera actualización. Lo único que hice diferente fue poner fetch() delante del enlace del evento.

17

Los nombres de los atributos y los valores de los atributos no numéricos en su archivo JSON deben ser dobles (""). Las comillas simples o sin comillas producen errores y no se crea el objeto de respuesta que podría utilizarse para crear los modelos y completar la colección.

So. Si cambia el contenido del archivo json a:

[ 
    { "text": "Amy", grade: 5 }, 
    { "text": "Angeline", grade: 26 }, 
    { "text": "Anna", grade: 55 }  
] 

debería ver el objeto de colección no vacío.

Puede cambiar su código para ver tanto el éxito y el fracaso de la siguiente manera:

AllStudents.fetch({ 
    url: "/init.json", 
    success: function() { 
      console.log("JSON file load was successful", AllStudents); 
     }, 
    error: function(){ 
     console.log('There was some error in loading and processing the JSON file'); 
    } 
    }); 

Para más detalles, probablemente será una buena idea para buscar en la forma de respuesta ajax objetos son creados.

+1

Tienes razón. Esta es la respuesta correcta. Esta es la respuesta correcta –

Cuestiones relacionadas