如何在骨干模型中设置属性

时间:2016-10-02 16:48:57

标签: javascript backbone.js

我正在尝试使用骨干来实现我的应用,但我可能会遇到一些误解。

我想在使用某些默认值时指定某些属性(标题等)。但是自定义属性没有设置,为什么?

        var DataMapper = {
            Models: {},
            Collections: {},
            Views: {},
            Templates: {}
        };


        DataMapper.Views.OperatorView = Backbone.View.extend({
            el: "#op-panel",
            operators: [],
            events: {
                "click #concat-op-btn": "addConcatOp"
            },
            addConcatOp: function () {
                var concatOperator = new DataMapper.Models.OpContainerBox({title: "Concat", inputCount: 2, outputCount: 1});
                this.operators.push(concatOperator);
                concatOperator.drawContainer();
            }
        });


        DataMapper.Models.OpContainerBox = Backbone.Model.extend({
            title: "Operator",
            inputCount: 0,
            outputCount: 0,
            defaults: {
                x: 400,
                y: 40,
                leaves: [],
                height: 20,
                width: 120
            },
            drawContainer: function () {
                console.log(this.title); //outputs "Operator" not "Concat"
            }
        });
        new DataMapper.Views.OperatorView();

1 个答案:

答案 0 :(得分:5)

Backbone模型属性与JavaScript对象属性不同。属性存储在attributes属性中,您使用getset来处理它们;属性已附加到this,可通过this.property_name直接访问。

当你这样说时:

DataMapper.Models.OpContainerBox = Backbone.Model.extend({
    title: "Operator"
});

title将是属性,而不是属性。当你这样说:

DataMapper.Models.OpContainerBox.new({
    title: 'Concat'
});

Backbone会将title属性设置为'Concat'

如果您将console.log来电更改为:

console.log(this.title, this.get('title'));

您应该在控制台中看到'Operator''Concat'

所有默认值都应该放在defaults属性中,如果任何默认值是可变的,那么你应该使用defaults函数来防止意外的参考共享:

DataMapper.Models.OpContainerBox = Backbone.Model.extend({
    defaults: function() {
        return {
            title: "Operator",
            inputCount: 0,
            outputCount: 0,
            x: 400,
            y: 40,
            leaves: [],
            height: 20,
            width: 120
        };
    },
    drawContainer: function () {
        console.log(this.get('title'));
    }
});

如果您不使用defaults的函数,则所有OpContainerBox个实例将通过原型共享完全相同的defaults.leaves数组。

您还需要确保使用get来访问属性:this.get('title')而不是this.title

此“通过原型参考共享”问题也可能导致您operators中的OperatorView数组出现问题,因此您可能想要这样说:

DataMapper.Views.OperatorView = Backbone.View.extend({
    el: "#op-panel",
    events: {
        "click #concat-op-btn": "addConcatOp"
    },
    initialize: function() {
        this.operators = [ ]; // <---- One distinct array per instance.
    },
    //...
});