Jos*_*arl 6 javascript backbone.js
是否有一种直接的方法将新模型项插入backbone.js的中间,Collection然后更新集合View以将新项目包含在正确的位置?
我正在使用控件来添加/删除列表中的项目.每个列表项都有自己的Model和View,和我有一个View对整个采集为好.
每个项目视图都有一个Duplicate按钮,用于克隆项目的模型,并将其插入到单击项目下方索引位置的集合中.
将项目插入集合很简单,但我无法弄清楚如何更新集合视图.我一直在尝试这样的事情:
ListView = Backbone.View.extend({
el: '#list-rows',
initialize: function () {
_.bindAll(this);
this.collection = new Items();
this.collection.bind('add', this.addItem);
this.render();
},
render: function () {
this.collection.each(this.addItems);
return this;
},
addItem: function (item) {
var itemView = new ItemView({ model: item }),
rendered = itemView.render().el,
index = this.collection.indexOf(item),
rows = $('.item-row');
if (rows.length > 1) {
$(rows[index - 1]).after(rendered);
} else {
this.$el.append(rendered);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个实现有点工作,但是当我添加一个新项目时,我会遇到奇怪的错误.我相信我可以解决这些问题,但......
我脑子里有一个声音告诉我,有更好的方法可以做到这一点.必须手动找出插入新的位置ItemView似乎真的很hacky - 集合视图不应该知道如何重新渲染集合吗?
有什么建议?
我不认为在添加新元素时重新渲染整个集合是最佳解决方案.它比在正确的位置插入新项目慢,特别是如果列表很长.
另外,请考虑以下方案.您在集合中加载了一些项目,然后添加了n更多项目(比如用户单击"加载更多"按钮).要执行此操作,您将调用fetch()方法add: true作为选项之一传递.当从服务器接收到数据时,"添加"事件会被触发n,并且您最终会重新呈现列表n时间.
我实际上在你的问题中使用了代码的变体,这是我对'add'事件的回调:
var view, prev, prev_index;
view = new ItemView({ model: new_item }).render().el;
prev_index = self.model.indexOf(new_item) - 1;
prev = self.$el.find('li:eq(' + prev_index + ')');
if (prev.length > 0) {
prev.after(view);
} else {
self.$el.prepend(view);
}
Run Code Online (Sandbox Code Playgroud)
所以,基本上我只是使用:eq()jQuery选择器而不是像你那样获取所有元素,应该使用更少的内存.
我所做的通常方法是让ListView渲染每个ItemView功能render。然后我将add事件绑定到render函数,如下所示:
ListView = Backbone.View.extend({
el: '#list-rows'
, initialize: function () {
_.bindAll(this);
this.collection = new Items();
this.collection.bind('add', this.render);
this.render();
}
, render: function () {
this.$el.empty();
var self = this;
this.collection.each(function(item) {
self.$el.append(new ItemView({ model: item }).render().el);
});
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
每次调用 时this.collection.add(someModel, {at: index}),视图都会相应地重新渲染。