Backbone听嵌套模型/集合?

时间:2014-05-07 14:19:44

标签: javascript backbone.js marionette

以下只是对我正在做的事情的粗略概念,该集合是嵌套的,我需要在getMax()更改时调用this.collection.get('players')

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);
    }
});

我正在使用骨干关系,然后决定放弃它,现在我想我可能再次需要它,但希望有一种更简单的方法。

因此虽然可能有更好的方法来编写getMax()函数(显然现在已经传入静态团队)但如果我无法更新getMax()时我就无法使用它玩家模型中的点数正在发生变化。

所以我的问题是,我可以在没有主干关系的情况下听取嵌套模型的更改吗?我将如何做?

3 个答案:

答案 0 :(得分:2)

看看Backbone.DeepModel:您可以订阅更改:玩家。*活动

或坚持骨干关系。

答案 1 :(得分:2)

我只想为任何需要此功能的人提供自制解决方案。基本上,您只需在模型声明中创建一个新方法,通常会在触发它们时更新属性,以便您可以使用model.on("更改: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!"

答案 2 :(得分:0)

我无法获得嵌套模型的深层模型,但这似乎是一个很好的解决方案,它很简单,但我没想到会像这样使用它。

this.collection.each(function(team) {
    team.players.bind('change', this.render);
}, this);