[英]Backbone.js : Remove an item from a collection
I'm using backbone.js to implement a buddy list aka Roster. 我正在使用backbone.js来实现一个名为Roster的好友列表。 My backbone view for the Roster collection and individual
rosterEntry
are as follows: 我对名册收集和独立的骨干视图
rosterEntry
如下:
Slx.Roster.Views.RosterEntry = Backbone.View.extend({
tagName: "li",
className : "rosterEntry clearfix",
templateSelector: '#rosterEntryTemplate',
initialize: function() {
_.bindAll(this, 'render');
this.model.bind('change', this.render);
this.model.bind('remove', this.remove);
this.template = _.template($("#rosterEntryTemplate").html());
},
remove: function () {
debug.log("Called remove event on model");
$(this.el).remove();
},
render: function() {
var renderedContent = this.template(this.model.toJSON());
this.id = this.model.Id;
$(this.el).attr('id', "friendid-" + this.model.get("id")).html(renderedContent);
return this;
}
});
Slx.Roster.Views.Roster = Backbone.View.extend({
el: "div#roster-container",
initialize: function () {
_.bindAll(this, 'render', 'add', 'remove');
this.template = _.template($("#rosterTemplate").html());
this.collection.bind('reset', this.render);
this.collection.bind('add', this.add);
this.collection.bind('remove', this.remove);
},
add: function (rosterEntry) {
var view = new Slx.Roster.Views.RosterEntry(
{
model: rosterEntry
});
$(this.el).append(view.render().el);
},
remove: function (model) { // if I ommit this then the whole collection is removed!!
debug.log("called remomve on collection");
},
render: function () {
var $rosterEntries, collection = this.collection;
$(this.el).html(this.template({}));
$rosterEntries = this.$('#friend-list');
_.each(collection.models, function (model) {
var rosterEntryView = new Slx.Roster.Views.RosterEntry({
model: model,
collection: collection
});
$(this.el).find("ul#friend-list").append(rosterEntryView.render().el);
}, this);
return this;
}
})
I'm testing for now using the Firebug console and can populate the roster just fine by executing the following: 我正在使用Firebug控制台进行测试,并且可以通过执行以下命令来填充名单:
collection = new Slx.Roster.Collection
view = new Slx.Roster.Views.Roster({collection:collection})
collection.fetch()
Adding to a collection also works fine, by executing the following in the Firebug console: 通过在Firebug控制台中执行以下操作,添加到集合也可以正常工作:
collection.add(new Slx.Roster.Model({username:"mickeymouse"})
and the new rosterEntry
is added to the Roster. 并将新的
rosterEntry
添加到名册中。
My problem is that collection.remove(5)
removes from the in-memory collection, but does nothing to update the DOM. 我的问题是
collection.remove(5)
从内存中的集合中删除,但没有更新DOM。
Strangely, if I ommit the remove()
function from the Roster View, all the entries in the roster are removed. 奇怪的是,如果我从名单视图中省略了
remove()
函数,则会删除名单中的所有条目。 If I add this method with nothing in it but a console log, it the remove method on both the Roster and RosterEntry
views is called - although I'm not sure why but they are out of order! 如果我添加此方法除了控制台日志之外没有任何内容,则会调用Roster和
RosterEntry
视图上的remove方法 - 虽然我不确定为什么但是它们不正常!
["Called remove event on model"]
["called remomve on collection"]
if I delete the remove function from the RosterEntry model I get this error: 如果我从RosterEntry模型中删除remove函数,我会收到此错误:
TypeError: this.$el is undefined
this.$el.remove();
What am I doing wrong? 我究竟做错了什么? How do I remove the element from the DOM when it is removed from the collection?
从集合中删除元素时如何从DOM中删除元素?
I think you have a problem with the context
in every event bind definition. 我认为每个事件绑定定义中的
context
都有问题。
Try to change this: 试着改变这个:
this.model.bind('remove', this.remove);
For this: 为了这:
this.model.bind('remove', this.remove, this);
I know you have tried to solve this with the bindAll
, but bindAll
is wrapping every call to the listed methods with the context of the actual object, but this can't do anything if you are calling the same method on other object :). 我知道你试图用
bindAll
来解决这个bindAll
,但是bindAll
用实际对象的上下文来包装对列出的方法的每次调用,但如果你在其他对象上调用相同的方法 ,这就无法做任何事情:)。
I have reading more.. looks like bindAll
and the third paramater of the bind
command do exactly the same. 我阅读更多..看起来像
bindAll
和bind
命令的第三个参数完全相同。 So maybe you can use the one or the other. 所以也许你可以使用其中一个。
The because is not working the bindAll
in the model.remove
is because you forgot to add it to the _.bindAll(this, 'render')
line, look in your code. 该因为不正常的
bindAll
在model.remove
是因为你忘了把它添加到_.bindAll(this, 'render')
行,看在你的代码。 And my suggestion fixed it because as I say both approachs do the same. 我的建议修正了它,因为我说两种方法都是一样的。
What all this is doing is assuring that the calls to the listed methods ( render, remove, ...
in one case or this.remove
in the other) are gonna interpretate this
as a reference to the actual object. 这一切都做的是确保该所列出的方法调用(
render, remove, ...
在一个案件或this.remove
的除外)都打算interpretate this
为实际对象的引用。 This can look stupid but this
is very volatile in JS. 这看起来愚蠢,但是
this
是在JS非常不稳定 。
Don't worry if you are still confused with the this
thing, I have dealing with it for long and still not completely cofindent . 如果你仍然
this
件事情感到困惑,请不要担心,我已经处理了很长时间而且还没有完全结合 。
Maybe essais like this can help us. 也许这样的essais可以帮助我们。
Have you tried the following? 你试过以下吗?
this.listenTo(this.model, "remove", this.remove);
That seems to work for me and I like the way it reads a little bit better. 这似乎对我有用,我喜欢它看起来更好一点的方式。
The remove methods on both the views are probably being called because you've bound to remove on both the model and the collection. 可能正在调用两个视图上的remove方法,因为您必须同时删除模型和集合。
In RosterEntry: 在RosterEntry中:
this.model.bind('remove', this.remove);
In Roster: 在名册中:
this.collection.bind('remove', this.remove);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.