Take a look on Backbone.DeepModel: you could subscribe to change:players.* event
or stick with backbone-relational.
Pregunta
So below is just a rough idea of what I am doing, the collection is nested and I need to call getMax()
when this.collection.get('players')
changes
module.exports = LeadersCollectionView = Marionette.CompositeView.extend({
className: 'live-stats',
template: require('../../../templates/leaders/live-stats.hbs'),
initialize: function() {
this.listenTo(this.collection, 'change', this.render);
//this.listenTo(this.collection.get('players'), 'change', this.render);
},
getMax : function(attribute) {
console.log('getMax called')
var home = this.collection.get('5368dcc1227a937829b2cb4a').players.models;
var away = this.collection.get('5368dcd9227a937829b2cb4c').players.models;
leaders = new PlayersCollection(home.concat(away))
return leaders.max(function(leader) {
return leader.get(attribute);
});
},
templateHelpers:function(){
return {
maxPoints: this.getMax('points').get('player_name')
}
},
itemView: leadersView,
appendHtml: function(collectionView, itemView){
collectionView.$('.live-data .created-teams').append(itemView.el);
}
});
I was using backbone-relational, and then decided to drop it, now I think I may need it again, but hopefully there is an easier way.
So while there may be a better way to write the getMax()
function (obviously static teams passed in as of now) I can't really use it if I cant update the getMax()
when the points are changing within the players models.
So my question can I listen to changes on a nested model without backbone-relational and how would I do that?
Solución
Take a look on Backbone.DeepModel: you could subscribe to change:players.* event
or stick with backbone-relational.
Otros consejos
I just wanted to chime in with a homemade solution for anyone who needs this. Essentially, you just create a new method in the model declaration that will generically let you update attributes while triggering them so you can utilize model.on("change:my.nested.attr");
// Create your model; inside create a new method that will
// set nested attributes (ie: setNestedAttr())
var nestedBackboneAttributeSample = Backbone.Model.extend({
defaults: {
id: null,
nestedProperties: {
name: null,
age: null,
email: null
}
},
/**
* [setNestedAttr Set nested attribute and fire change event]
* @param {[type]} nestedObj [object inside of this.attributes]
* @param {[type]} property [property inside of nestedObj]
* @param {[type]} value [value to replace nestedObj[property] with]
*/
setNestedAttr: function(nestedObj, property, value) {
// get current nested obj from this.attributes
var ref = this.get(nestedObj)
triggerString = "change:" + nestedObj + "." + property;
console.log("Nested Object retrieved =>");
console.log(ref);
// if this.attributes.nestedObj has the property and
// value is defined
if (ref.hasOwnProperty(property) && value != undefined) {
ref[property] = value;
this.set({ nestedObj: ref });
// manually trigger.. backbone doesn't monitor nested attrs
this.trigger(triggerString);
}
}
});
// now, let's run some sampel code to give you
// an idea of how to use this.
var x = new nestedBackboneAttributeSample();
// setup event handler for on change w/specific nested attr
x.on("change:nestedProperties.name", function() {
console.log("this event was fired!");
});
x.setNestedAttr("nestedProperties", "name", "Github")
// output => "this event was fired!"
I couldnt get deepmodel or nestedmodels to work, but this seems like a great solution, it's so simple but I didn't think of using it like this.
this.collection.each(function(team) {
team.players.bind('change', this.render);
}, this);