Javascript Backbone.js 将更改事件绑定到模型内的集合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6127046/
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 binding a change event to a collection inside a model
提问by Ad Taylor
I'm pretty new to Backbone so excuse me if this question is a little obvious. I am having problems with a collection inside of a model. When the collection changes it doesn't register as a change in the model (and doesn't save).
我对 Backbone 很陌生,所以如果这个问题有点明显,请原谅。我在模型内部的集合时遇到问题。当集合更改时,它不会注册为模型中的更改(并且不会保存)。
I have set up my model like so:
我已经像这样设置了我的模型:
var Article = Backbone.Model.extend({
defaults: {
"emsID" : $('html').attr('id')
},
initialize: function() {
this.tags = new App.Collections.Tags();
},
url: '/editorial_dev.php/api/1/article/persist.json'
});
This works fine if I update the tags collection and manually save the model:
如果我更新标签集合并手动保存模型,这可以正常工作:
this.model.tags.add({p : "a"});
this.model.save();
But if the model is not saved the view doesn't notice the change. Can anyone see what I am doing wrong?
但是如果模型没有保存,视图不会注意到变化。谁能看到我做错了什么?
回答by Raynos
initialize: function() {
this.tags = new App.Collections.Tags();
var model = this;
this.tags.bind("change", function() {
model.save();
});
},
Bind to the change
event on the inner collection and just manually call .save
on your outer model.
绑定到change
内部集合上的事件,只需手动调用.save
外部模型。
回答by Eric Hu
This is actually an addendum to @Raynos answer, but it's long enough that I need answer-formatting instead of comment-formatting.
这实际上是@Raynos 答案的附录,但它足够长,我需要答案格式而不是评论格式。
Clearly OP wants to bind to
change
andadd
here, but other people may want to bind todestroy
as well. There may be other events (I'm not 100% familiar with all of them yet), so binding toall
would cover all your bases.remove
also works instead ofdestroy
. Note that bothremove
anddestroy
fire when a model is deleted--firstdestroy
, thenremove
. This propagates up to the collection and reverses order:remove
first, thendestroy
. E.g.model event : destroy model event : remove collection event : destroy collection event : remove
There's a gotcha with custom event handlers described in this blog post.
Summary: Model-level events should propagate up to their collection, but can be prevented if something handles the event first and calls
event.stopPropagation
. If the event handler returnsfalse
, this is a jQuery shortcut forevent.stopPropagation(); event.preventDefault();
Calling
this.bind
in a model or collection refers to Underscore.js'sbind, NOTjQuery/Zepto's. What's the difference? The biggest one I noticed is that you cannot specify multiple events in a single string with space-separation. E.g.this.bind('event1 event2 ...', ...)
This code looks for the event called
event1 event2 ...
. In jQuery, this would bind the callback toevent1
,event2
, ... If you want to bind a function to multiple events, bind it toall
or callbind
once for each event. There is an issuefiled on github for this, so this one will hopefully change. For now (11/17/2011), be wary of this.
显然 OP 想要绑定到
change
和add
这里,但其他人可能也想绑定到destroy
。可能还有其他事件(我还不是 100% 熟悉所有事件),因此绑定到all
将涵盖您的所有基础。remove
也可以代替destroy
. 请注意,当删除模型时,remove
和 都会destroy
触发 - 首先是destroy
,然后是remove
。这会传播到集合并颠倒顺序:remove
首先,然后destroy
。例如model event : destroy model event : remove collection event : destroy collection event : remove
这篇博文中描述了自定义事件处理程序的一个问题。
总结:模型级事件应该传播到它们的集合,但如果某些东西首先处理事件并调用
event.stopPropagation
. 如果事件处理程序返回false
,这是一个 jQuery 快捷方式event.stopPropagation(); event.preventDefault();
调用
this.bind
模型或集合是指Underscore.js 的绑定,而不是jQuery/Zepto 的。有什么不同?我注意到的最大一个问题是,您不能在单个字符串中使用空格分隔指定多个事件。例如this.bind('event1 event2 ...', ...)
此代码查找名为 的事件
event1 event2 ...
。在 jQuery 中,这会将回调绑定到event1
,event2
, ... 如果要将函数绑定到多个事件,请将其绑定到all
或bind
为每个事件调用一次。在 github 上为此提交了一个问题,所以这个问题有望改变。现在 (11/17/2011),请注意这一点。