最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Backbone.js binding a change event to a collection inside a model - Stack Overflow

programmeradmin2浏览0评论

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).

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?

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).

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?

Share Improve this question edited Dec 5, 2011 at 18:13 Tomasz Nurkiewicz 341k71 gold badges711 silver badges678 bronze badges asked May 25, 2011 at 15:34 Ad TaylorAd Taylor 2,7755 gold badges27 silver badges32 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 12
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.

This is actually an addendum to @Raynos answer, but it's long enough that I need answer-formatting instead of comment-formatting.

  1. Clearly OP wants to bind to change and add here, but other people may want to bind to destroy as well. There may be other events (I'm not 100% familiar with all of them yet), so binding to all would cover all your bases.

    remove also works instead of destroy. Note that both remove and destroy fire when a model is deleted--first destroy, then remove. This propagates up to the collection and reverses order: remove first, 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.bind in a model or collection refers to Underscore.js's bind, NOT jQuery/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 all or call bind once for each event. There is an issue filed on github for this, so this one will hopefully change. For now (11/17/2011), be wary of this.

发布评论

评论列表(0)

  1. 暂无评论