listen to a collection add/change as a model attri

2019-05-06 15:04发布

问题:

I have a Measure View, and it has an associated Measure Model, which has two collections, RepresentationsCollection and BeatsCollection. The Measure View has nested child Representation views, each with their own representation model, and all representation models share the same attribute of a reference to the Measure View's BeatsCollection.

I know that if you are listening to a change event, the collection won't respond when something is added. You are supposed to use bind. The docs aren't the best. So if the child Representation View looks like this:

representation.View = Backbone.View.extend({
  initialize: function(options) {
    // this.beatsCollection is a reference to the Parent Measure View attribute beatsCollection which is a collection
    this.model.listenTo(this, 'change:beatsCollection', this.render);
    this.model.on('change:beatsCollection', this.render, this);
    this.bind.listenTo(this, 'change:beatsCollection', this.render);
  },

and here is the model:

representation.Model = Backbone.Model.extend({
  initialize: function(options) {
    console.log(options); 
    this.idAttribute = options.idAttribute;
    this.type = options.type;
    this.beatsCollection = options.beatsCollection;
 } 

How do I listen for the attribute on this views associated model, which has an attribute, that is linked to a collection on another model?

Here is a Plnkr: http://plnkr.co/edit/z4mWqo1v0nDe13TiB9r3?p=preview
First click 'add a representation'.
Second, click 'add a beat' and notice that the number of beats don't update. Third, if you click 'add a representation' again, it will add another one with the correct number of beats. In the Representation.js View, how do we get the Representation Views to re-render, when ANY of the sibling views click 'add a beat'

回答1:

updated Plnkr: http://plnkr.co/edit/JtyxnhaGlPVijhbRPt5v?p=preview

trick was here in representation.View replacing

initialize: function(options) {
  if(options.model){this.model=options.model;}
  this.model.listenTo(this, 'change:beatsCollection', this.render);
  this.model.on('change:beatsCollection', this.render, this);
  this.model.on('change:beatsCollection', this.render, this);
  //this.model.on('destroy', this.remove, this);
},

with

initialize: function(options) {
  if(options.model){this.model=options.model;}
  this.listenTo(this.model.beatsCollection,  'add remove reset', this.render);
},