2013-10-20 17 views
12

Ich versuche, meine Backbone-Sammlung von einer lokalen API aus zu füllen und die Ansicht zu ändern, um die Daten anzuzeigen. Der Aufruf fetch() in meiner Sammlung scheint erfolgreich zu sein, und die Daten werden abgerufen, aber die Abrufoperation aktualisiert die Modelle in der Auflistung nicht.Backbone-Sammlung ruft Daten ab, legt aber keine Modelle fest

Dies ist, was ich für mein Modell und Sammlung haben:

var Book = Backbone.Model.extend(); 

var BookList = Backbone.Collection.extend({ 

    model: Book, 
    url: 'http://local5/api/books', 

    initialize: function(){ 
     this.fetch({ 
      success: this.fetchSuccess, 
      error: this.fetchError 
     }); 
    }, 

    fetchSuccess: function (collection, response) { 
     console.log('Collection fetch success', response); 
     console.log('Collection models: ', this.models); 
    }, 

    fetchError: function (collection, response) { 
     throw new Error("Books fetch error"); 
    } 

}); 

und ich habe meine Ansichten wie dies getan:

var BookView = Backbone.View.extend({ 

    tagname: 'li', 

    initialize: function(){ 
     _.bindAll(this, 'render'); 
     this.model.bind('change', this.render); 
    }, 

    render: function(){ 
     this.$el.html(this.model.get('author') + ': ' + this.model.get('title')); 
     return this; 
    } 

}); 

var BookListView = Backbone.View.extend({ 

    el: $('body'), 

    initialize: function(){ 
     _.bindAll(this, 'render'); 

     this.collection = new BookList(); 
     this.collection.bind('reset', this.render) 
     this.collection.fetch(); 

     this.render(); 
    }, 

    render: function(){ 
     console.log('BookListView.render()'); 
     var self = this; 
     this.$el.append('<ul></ul>'); 
     _(this.collection.models).each(function(item){ 
      console.log('model: ', item) 
      self.appendItem(item); 
     }, this); 
    } 

}); 

var listView = new BookListView(); 

und meine API gibt JSON-Daten wie folgt aus:

[ 
    { 
     "id": "1", 
     "title": "Ice Station Zebra", 
     "author": "Alistair MacLaine" 
    }, 
    { 
     "id": "2", 
     "title": "The Spy Who Came In From The Cold", 
     "author": "John le Carré" 
    } 
] 

Wenn ich diesen Code ausführen ich dies in der Konsole:

BookListView.render() app.js:67 
Collection fetch success Array[5] 
Collection models: undefined 

was zeigt mir an, dass der Abrufaufruf die Daten OK erhält, aber dass es die Modelle damit nicht bevölkert. Kann mir jemand sagen, was ich hier falsch mache?

Antwort

12

Ihre fetchSuccess Funktion sollte collection.models nicht this.models haben.

console.log('Collection models: ', collection.models); 

und bitte beachten Sie die Vorschläge von @Pappa.

+0

Vielen Dank user10, das war die Antwort! Ich finde immer noch meinen Weg und habe nicht bemerkt, dass "dies" den globalen Umfang innerhalb von fetchSuccess hat - ich bin mir immer noch nicht 100% sicher warum, aber ich finde, wenn ich "this" an fetchSuccess binde, wenn ich die Sammlung initiiere der Umfang der Sammlung. –

+0

'fetchSuccess' ist ein Callback, der von' Backbone.sync' aufgerufen wird und von Backbone.js im globalen Gültigkeitsbereich ausgeführt wird. – user10

+0

Ohhhh also deshalb! Danke Benutzer10. –

8

Sie rufen fetch zweimal in Ihrer BookList-Sammlung auf, einmal beim Initialisieren und dann erneut, wenn Ihre BookListView-Datei initialisiert wird. Es ist eine schlechte Praxis, wenn eine Sammlung sich im Moment der Instanziierung selbst füllt. Sie geben Ihre Ansicht auch zweimal innerhalb ihres Initialisierungsaufrufs wieder, einmal als Reaktion auf das Ereignis "Zurücksetzen", und dann rufen Sie sie auch direkt an.

Ich würde empfehlen, die Initialisierungsfunktion vollständig aus Ihrer BookList-Auflistung zu entfernen und den Aufruf von this.render() zu entfernen; am Ende des Initialisierungsanrufs von BookListView.

+1

Danke Pappa, ich nehme deinen sehr nützlichen Rat! –

+0

Wenn eine Ansicht eine Initialisierungsmethode hat, ruft sie automatisch this.render() auf? –

+1

@AlexMills Nein, Sie müssen die Renderfunktion manuell aufrufen. – Kevin

Verwandte Themen