2012-09-29 16 views
5

Tengo una Colección App.listingList donde se llaman fetch() con add:true.Backbone.js: Después de hacer Fetch(), renderizar solo los nuevos modelos

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

Problema: ¿Cómo pueden los modelos recién añadidos que sus opiniones sean prestados, sin volver a prestar los puntos de vista de los modelos existentes. Esto significa que no puedo hacer:

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

Intento # 1

representación de perspectiva sobre el caso de la colección add, no puedo encontrar una manera de acceder a los nuevos modelos para hacer

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

Intento # 2

Traté de tener una segunda Col Para ver el siguiente fetch y comparar los modelos de ambas colecciones con underscore.js, _.without(), pero la matriz devuelta todavía contiene los elementos encontrados en la segunda serie pasada como parámetro. El uso de _difference() también devuelve la misma matriz pasada como la primera matriz.

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 salida

Desde pasé en 2 arrays idénticos en _.difference() y _.without(), la salida debe ser []. Pero no es así:/Tal vez porque cid es diferente, por lo que cada uno de ellos se tratan como únicos.

enter image description here

Respuesta

5

Cuando haces un collection.bind('add', this.renderNew, this); éste pasa automáticamente el modelo añadido a su método como argumento.

Incluya el argumento en su método y debe tener acceso al nuevo modelo.

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

Sé que esto es una vieja pregunta, pero yo estaba teniendo el mismo problema y encontré esta respuesta, así que pensé que me gustaría añadir un enfoque alternativo. No estoy seguro de lo eficiente que es, pero funciona. Estoy usando esto para soportar una función de desplazamiento infinito.

estoy usando Backbone 1.2.1, por lo que en la colección buscar, estoy usando remove:false en lugar de la add:true desaprobado por los documentos aquí: http://backbonejs.org/#Collection-fetch

El enfoque básico es establecer un atributo rendered a true en cada elemento de la colección cuando se procesa por primera vez, luego utilícelo para ignorar elementos procesados ​​previamente en recuperaciones posteriores.

del modelo y de la colección:

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

Vistas:

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

Fetch función:

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