2012-09-29 21 views
5

Ho una collezione App.listingList dove i successivi fetch() vengono chiamati con add:true.Backbone.js: Dopo aver eseguito Fetch(), visualizza solo i nuovi modelli

App.listingList.fetch({ 
     data: {some:data}, 
     processData: true, 
     add: true 
}); 

Problema: Come possono i modelli appena aggiunti avere il loro parere reso, senza re-rendering il punto di vista dei modelli esistenti. Ciò significa che non posso fare:

this.collection.each(function(listing, index) { 
    new ListingMarkerView({ model:listing }).render(); 
}, this); 

Tentativo # 1

rendering della vista sulla manifestazione della collezione add, non riesco a trovare un modo per accedere ai nuovi modelli di rendere

ListingListView = Backbone.View.extend({ 

    initialize: function() { 
     this.collection.bind('add', this.renderNew, this); 
    }, 

    render: function() { 
     console.log('render ListingListView'); 
     this.collection.each(function(listing, index) { 
      new ListingMarkerView({ model:listing }).render(); 
     }, this); 
     return this; 
    }, 

    renderNew: function() { 
     // How do I grab the new models? 
     new ListingMarkerView({ model:listing }).render(); // wont work 
     return this; 
    } 
}); 

Tentativo n. 2

Ho provato ad avere un secondo Col per fare il successivo fetch e confrontare i modelli di entrambe le raccolte usando lo underscore.js _.without(), ma l'array restituito contiene ancora gli elementi trovati nel 2 ° array passato come parametro. L'utilizzo di _difference() ha inoltre restituito la stessa matrice passata come prima matrice.

App.listingListNew.fetch({ 
     data: {some:data}, 
     processData: true, 
     success: function() { 
      console.log(App.listingListNew.models); 
      console.log(App.listingList.models); 
      console.log(_.without(App.listingListNew.models, App.listingList.models)); 
      console.log(_.difference(App.listingListNew.models, App.listingList.models)); 
     } 
}); 

console.log uscita

Da passai 2 allineamenti identici in _.difference() e _.without(), l'uscita dovrebbe essere []. Ma non lo è:/Forse perché cid è diverso, quindi ognuno di essi viene trattato come unico?

enter image description here

risposta

5

Quando si esegue un collection.bind('add', this.renderNew, this); passa automaticamente il modello aggiunto al tuo metodo come argomento.

Includere l'argomento nel metodo e si dovrebbe avere accesso al nuovo modello.

renderNew: function(newModel) { 
    new ListingMarkerView({ model:newModel }).render(); 
    return this; 
} 
0

So che questa è una vecchia questione, ma ho avuto lo stesso problema e mi sono imbattuto in questa risposta così ho pensato che vorrei aggiungere un approccio alternativo. Non sono sicuro di quanto sia efficiente, ma funziona. Lo sto usando per supportare una funzione di scorrimento infinito.

sto usando Backbone 1.2.1, così nella collezione fetch, sto usando remove:false invece del deprecato add:true per la documentazione qui: http://backbonejs.org/#Collection-fetch

L'approccio di base è quello di impostare un attributo rendered a true su ogni elemento della raccolta al momento del primo rendering, quindi usalo per ignorare gli oggetti precedentemente resi su recuperi successivi.

modello e Collezione:

MyApp.Item = Backbone.Model.extend({}); 

MyApp.ItemList = Backbone.Collection.extend({ 
model: MyApp.Item, 
    url: '/api/item/', 
    parse : function(response){ 
     if (response.stat) { 
      return _.map(response.content, function(model, id) { 
       model.id = id; 
       return model; 
      }); 
     } 
    } 
}); 

Visualizzazioni:

MyApp.loadMyItems = function() { 
    MyApp.gettingData = true; //flag for infinite scroll 
    MyApp.myItems.fetch({ 
     traditional: true, 
     remove:false, 
     data: { 
      u_id: MyApp.User.id, 
      order: 'create_date:desc', 
      start: MyApp.myItems.length, 
      num_items: 10 
     }, 
     success: function(){ 
      MyApp.gettingData = false; //flag for infinite scroll 
      MyApp.myItemsView.render(); 
     } 
    }); 
}; 

Calling::

//on initial page load 
MyApp.myItems = new MyApp.ItemsCollection(); 
MyApp.myItemsView = new MyApp.ItemListView({ 
          collection: MyApp.myItems, 
          el: $('#my-items') 
         }); 
MyApp.loadMyItems(); 

//infinite scroll 
$('#items .infinite-scroll').on('loadmore', function() { 
    if (!MyApp.gettingData) { 
     MyApp.loadMyItems(); 
    } 
}); 

MyApp.ItemListView = Backbone.View.extend({ 
    tagName: 'ul', 
    className: 'item-list', 
    render: function() { 
     this.collection.each(function(item){ 
      //don't render items that have already been rendered! 
      if (!item.rendered) { 
       var itemListDetailView = new MyApp.ItemListDetailView({model: item}); 
       this.$el.append(itemListDetailView.render().el); 
       item.rendered = true; 
      } 
     }, this) 
     return this; 
    } 
}); 

MyApp.ItemListDetailView = Backbone.View.extend({ 
    tagName: 'li', 
    className: 'item-list-detail', 
    render: function() { 
     $(this.el).html('<div class="item-title">' + this.model.get('title') + '</div>'); 
     return this; 
    } 
}); 

funzione Fetch

Problemi correlati