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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:21:31  来源:igfitidea点击:

Backbone.js binding a change event to a collection inside a model

javascriptjquerybackbone.js

提问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 changeevent on the inner collection and just manually call .saveon 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 答案的附录,但它足够长,我需要答案格式而不是评论格式。

  1. Clearly OP wants to bind to changeand addhere, but other people may want to bind to destroyas well. There may be other events (I'm not 100% familiar with all of them yet), so binding to allwould cover all your bases.

    removealso works instead of destroy. Note that both removeand destroyfire when a model is deleted--first destroy, then remove. This propagates up to the collection and reverses order: removefirst, then destroy. E.g.

    model event      :      destroy
    model event      :      remove
    collection event :      destroy
    collection event :      remove
    
  2. 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 returns false, this is a jQuery shortcut for event.stopPropagation(); event.preventDefault();

  3. Calling this.bindin 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 to event1, event2, ... If you want to bind a function to multiple events, bind it to allor call bindonce 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.

  1. 显然 OP 想要绑定到changeadd这里,但其他人可能也想绑定到destroy。可能还有其他事件(我还不是 100% 熟悉所有事件),因此绑定到all将涵盖您的所有基础。

    remove也可以代替destroy. 请注意,当删除模型时,remove和 都会destroy触发 - 首先是destroy,然后是remove。这会传播到集合并颠倒顺序:remove首先,然后destroy。例如

    model event      :      destroy
    model event      :      remove
    collection event :      destroy
    collection event :      remove
    
  2. 这篇博文中描述了自定义事件处理程序的一个问题。

    总结:模型级事件应该传播到它们的集合,但如果某些东西首先处理事件并调用event.stopPropagation. 如果事件处理程序返回false,这是一个 jQuery 快捷方式event.stopPropagation(); event.preventDefault();

  3. 调用this.bind模型或集合是指Underscore.js 的绑定,而不是jQuery/Zepto 的。有什么不同?我注意到的最大一个问题是,您不能在单个字符串中使用空格分隔指定多个事件。例如

    this.bind('event1 event2 ...', ...)
    

    此代码查找名为 的事件event1 event2 ...。在 jQuery 中,这会将回调绑定到event1, event2, ... 如果要将函数绑定到多个事件,请将其绑定到allbind为每个事件调用一次。在 github 上为此提交了一个问题,所以这个问题有望改变。现在 (11/17/2011),请注意这一点。