javascript Backbone.js:从集合中删除一个项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10178540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Backbone.js : Remove an item from a collection
提问by reach4thelasers
I'm using backbone.js to implement a buddy list aka Roster. My backbone view for the Roster collection and individual rosterEntry
are as follows:
我正在使用backbone.js 来实现一个好友列表又名名册。我对名册集合和个人的主干视图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"})
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. 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!
奇怪的是,如果我remove()
从名册视图中省略该功能,名册中的所有条目都将被删除。如果我添加此方法时除了控制台日志之外什么都没有,则会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 中移除元素?
采纳答案by fguillen
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
正在使用实际对象的上下文包装对列出的方法的每次调用,但是如果您在其他对象上调用相同的方法,这将无济于事:)。
Updated
更新
I have reading more.. looks like bindAll
and the third paramater of the bind
command do exactly the same. So maybe you can use the one or the other.
我读了更多……看起来bindAll
和bind
命令的第三个参数完全一样。所以也许你可以使用一个或另一个。
The becauseis 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. And my suggestion fixed it because as I say both approachs do the same.
在因为不工作bindAll
的model.remove
,因为你忘了把它添加到_.bindAll(this, 'render')
您的代码行,看看。我的建议修复了它,因为正如我所说,两种方法的作用相同。
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. This can look stupid but this
is very volatilein JS.
这一切所做的是确保对列出的方法的调用(render, remove, ...
在一种情况下或this.remove
另一种情况下)将解释this
为对实际对象的引用。这看起来很愚蠢,但在 JS 中this
非常不稳定。
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 thiscan help us.
也许像这样的散文可以帮助我们。
回答by moliveira
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.
这似乎对我有用,我更喜欢它的阅读方式。
回答by Marty Cortez
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:
在名册条目中:
this.model.bind('remove', this.remove);
In Roster:
在名册中:
this.collection.bind('remove', this.remove);