2012-02-24 21 views
16

Sto cercando di caricare alcuni dati in una collezione backbone da un file JSON locale, utilizzando questo codice molto semplice:Caricare i dati in una raccolta Backbone dal file 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); 

Nella dichiarazione console, AllStudents è vuota. Ma lo init.json è stato sicuramente caricato. Assomiglia a questo:

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

Cosa sto facendo di sbagliato?

UPDATE: Ho anche provato ad aggiungere un ascoltatore reset sopra la chiamata .fetch(), ma non è neanche sparare:

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

appare Nessun avviso.

UPDATE 2: Cercando questo script (qui riprodotto per intero): appare

$(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); 
    }); 
}); 

una sola istruzione console anche, nel terzo fetch() chiamata, ed è un oggetto vuoto.

Ora sono assolutamente sconcertato. Che cosa sto facendo di sbagliato?

Il file JSON viene servito come applicazione/json, quindi non ha nulla a che fare con quello.

+1

È una bella domanda. dovresti aver usato http://jsonlint.com/ per verificare il tuo JSON –

risposta

0

penso che è necessario aggiungere {add:true} alle opzioni di recupero,

se è stato assegnato il recupero su un variabile, si otterrebbe il risultato pure, ma poi il suo non all'interno della collezione si voleva

+0

Non penso che sia giusto - '{add: true}' aggiunge, piuttosto che sostituisce, il contenuto, ma voglio sostituire il contenuto. – Richard

10

Le operazioni di I/O in javascript sono quasi sempre asincrone e lo è anche con Backbone. Ciò significa che solo perché AllStudents.fetch è stato restituito, non ha ancora recuperato i dati. Pertanto, quando si preme la propria istruzione console.log, le risorse non sono state ancora recuperate. Si dovrebbe passare un callback per fetch:

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

o, in alternativa, utilizzare la nuova funzionalità di promessa in jQuery (fetch restituirà una promessa):

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

Hm: l'affermazione della console non viene mai visualizzata, come se il successo non venisse mai attivato. Il file 'init.json' viene sicuramente caricato, anche se ... – Richard

1

fetch() restituisce una notifica di 'successo' come già dichiarato, ma ciò significa solo che la richiesta del server è andata a buon fine. fetch() ha riportato alcuni JSON, ma deve ancora inserirli nella raccolta.

La raccolta attiva un evento di 'reset' quando il contenuto è stato aggiornato. Questo è quando la collezione è pronta per l'uso ...

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

Sembra che tu avessi questo nel tuo primo aggiornamento. L'unica cosa che ho fatto in modo diverso è stato mettere fetch() di fronte al binding dell'evento.

17

I nomi degli attributi e i valori degli attributi non numerici nel file JSON devono essere indicati con virgolette (""). Le virgolette singole o le virgolette non producono errori e non viene creato l'oggetto risposta che potrebbe essere utilizzato per creare i modelli e popolare la raccolta.

Così. Se si modifica il contenuto del file JSON su:

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

si dovrebbe vedere l'oggetto di raccolta non vuoto.

È possibile modificare il codice per vedere sia successo e fallimento come di seguito:

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'); 
    } 
    }); 

Per maggiori dettagli, probabilmente sarà una buona idea di guardare in al modo in cui vengono creati gli oggetti ajax risposta.

+1

Hai ragione. Questa è la risposta corretta. Questa è la risposta corretta –

Problemi correlati