我有一个集合App.listingList
,后面的fetch()
会被add:true
调用。
App.listingList.fetch({
data: {some:data},
processData: true,
add: true
});
问题:新添加的模型如何渲染其视图,而无需重新渲染现有模型的视图。这意味着我做不到:
this.collection.each( function(listing, index) {
new ListingMarkerView({ model:listing }).render();
}, this);
尝试#1
在集合的add
事件中呈现视图,我无法找到一种方法来访问要渲染的新模型
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;
}
});
尝试#2
我尝试使用第二个Collection来执行后续fetch
,并使用underscore.js' s _.without()
比较两个集合的模型,但返回的数组仍然包含找到的元素在作为参数传递的第二个数组中。使用_difference()
也返回了与第一个数组一样传递的相同数组。
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
输出
由于我将2个相同的数组传入_.difference()
和_.without()
,因此输出应为[]
。但它不是:/也许因为cid
不同,所以每一个都被视为唯一?
答案 0 :(得分:5)
执行collection.bind('add', this.renderNew, this);
时,它会自动将添加的模型作为参数传递给您的方法。
在您的方法中包含参数,您应该可以访问新模型。
renderNew: function(newModel) {
new ListingMarkerView({ model:newModel }).render();
return this;
}
答案 1 :(得分:0)
我知道这是一个老问题,但我遇到了同样的问题并遇到了这个问题,所以我想我会添加一个替代方法。我不确定它有多高效,但它确实有效。我正在使用它来支持无限滚动功能。
我正在使用Backbone 1.2.1,因此在集合提取中,我使用remove:false
而不是每个文档中已弃用的add:true
:http://backbonejs.org/#Collection-fetch
基本方法是在首次渲染时对集合中的每个项目设置rendered
属性为true
,然后使用该属性忽略后续渲染中先前渲染的项目。
模特和收藏:
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;
});
}
}
});
查看:
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;
}
});
获取功能:
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();
}
});
};
通话:
//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();
}
});