質問

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?

役に立ちましたか?

解決

Take a look on Backbone.DeepModel: you could subscribe to change:players.* event

or stick with backbone-relational.

他のヒント

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);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top