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

Sac*_*lla 0 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();
Run Code Online (Sandbox Code Playgroud)

mu *_*ort 5

骨干模型属性与JavaScript对象属性不同.属性存储在attributes属性中,您可以使用它们getset使用它们; 属性附加到this并直接访问this.property_name.

当你这样说:

DataMapper.Models.OpContainerBox = Backbone.Model.extend({
    title: "Operator"
});
Run Code Online (Sandbox Code Playgroud)

title将是一个属性,而不是属性.当你这样说:

DataMapper.Models.OpContainerBox.new({
    title: 'Concat'
});
Run Code Online (Sandbox Code Playgroud)

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

如果您将console.log通话更改为:

console.log(this.title, this.get('title'));
Run Code Online (Sandbox Code Playgroud)

你应该看到'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'));
    }
});
Run Code Online (Sandbox Code Playgroud)

如果您不使用函数,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.
    },
    //...
});
Run Code Online (Sandbox Code Playgroud)