2013-10-20 14 views
12

Sto tentando di popolare la mia raccolta Backbone da un'API locale e modificare la visualizzazione per mostrare i dati. La chiamata fetch() nella mia raccolta sembra avere successo e acquisisce i dati, ma l'operazione di recupero non aggiorna i modelli nella raccolta.La raccolta backbone recupera i dati, ma non imposta i modelli

Questo è quello che ho per il mio modello e la raccolta:

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

}); 

e ho fatto le mie opinioni in questo modo:

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

e il mio API restituisce dati JSON come questo:

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

Quando eseguo questo codice ottengo questo nella console:

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

che indica a me che la chiamata di recupero sta ottenendo i dati OK, ma che non sta compilando i modelli con esso. Qualcuno può dirmi cosa sto facendo di sbagliato qui?

risposta

12

La funzione fetchSuccess deve avere collection.models non this.models.

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

e si prega di prendere in considerazione i suggerimenti forniti da @Pappa.

+0

Grazie mille utente10, questa è stata la risposta! Sto ancora cercando la mia strada e non mi sono reso conto che "questo" ha lo scopo globale all'interno di fetchSuccess - non sono ancora sicuro al 100% perché, ma trovo quando lego "this" a fetchSuccess per inizializzare la raccolta che ha l'ambito della collezione. –

+0

'fetchSuccess' è un callback chiamato da' Backbone.sync' che viene eseguito in ambito globale da Backbone.js. – user10

+0

Ohhhh, ecco perché! Grazie utente10. –

8

Si sta chiamando fetch sulla raccolta BookList due volte, una volta quando è inizializzata e nuovamente quando si inizializza BookListView. È considerata una cattiva pratica avere una collezione popolata nel momento stesso in cui viene istanziata. Stai anche eseguendo il rendering della tua vista due volte all'interno della sua chiamata di inizializzazione, una volta in risposta all'evento 'resetta' e poi la chiami anche direttamente.

Suggerirei di rimuovere completamente la funzione di inizializzazione dalla raccolta BookList e di rimuovere la chiamata a this.render(); alla fine della chiamata di inizializzazione di BookListView.

+1

Grazie Pappa, prenderò il tuo consiglio molto utile! –

+0

se una vista ha un metodo di inizializzazione chiama automaticamente this.render()? –

+1

@AlexMills No, devi chiamare manualmente la funzione di rendering. – Kevin

Problemi correlati