【问题标题】:backbone: initialize model subclasses with additional attributes主干:使用附加属性初始化模型子类
【发布时间】:2012-11-19 04:26:34
【问题描述】:

我是骨干新手,所以请多多包涵。我想创建一个集合,其中所有模型都有一些他们共享的关键属性以及一些他们不共享的其他属性。我认为最好的方法是扩展一个超类模型(包含所有共享属性的默认值),这样当我实例化一个新的子类模型时,这些属性被初始化,并且特定于子类的附加属性也被添加到该模型。我不知道如何做到这一点,但这是我一直在努力的方向:

app.Fruit = Backbone.Model.extend(
{

    defaults: {
        name: "none",
        classification: "none",
        color: "none"
    },

    initialize: function()
    {
        console.log("Fruit Initialized");
    }

});

app.Apple = app.Fruit.extend(
{

    url: "/php/Apple.php",

    initialize: function()
    {
        console.log("Apple initialized");
        // somehow fetch additional information from server
        // and add sublcass-specific attributes to model
        // (for example, in the case of an apple, an attribute called cultivar)
    }

});


var FruitCollection = Backbone.Collection.extend(
{

    model: function(attributes, options)
    {

        switch(attributes.name)
        {

        case "Apple":
            return new app.Apple(attributes, options);
            break;

            default:
            return new app.Fruit(attributes, options);
            break;

        }

    }

    // ...

});

app.fruitCollectionCurrent = new FruitCollection([
    {name: "Apple"},
    {name: "Orange"}
]);

// logs: Fruit Initialized

任何关于如何正确初始化具有附加属性的子类的建议将不胜感激。

谢谢。

编辑:解决方案

我想我会发布最终为我工作的代码......感谢@Mohsen:

app.Fruit = Backbone.Model.extend(
{

    defaults: {
        name: "none",
        classification: "none",
        color: "none"
    },

    initialize: function()
    {
        console.log("Fruit Initialized");
    }

});

app.Apple = app.Fruit.extend(
{

    url: "/php/Apple.php",

    initialize: function()
    {
        console.log("Apple initialized");
        return this.fetch();
    }

});

我什至不需要子类中的异步调用,因为我没有为 Fruit 获取任何额外的数据(Fruit 的属性只是在构造函数中设置),只为 Apple 获取。我真正想要的是使用指定 URL 调用 this.fetch() 。对不起,如果这个问题让事情看起来更复杂......

【问题讨论】:

    标签: javascript inheritance backbone.js model


    【解决方案1】:

    在层次结构方面,Backbone 并不容易使用。我通过在子模型/集合初始化程序中调用父模型/集合初始化程序来解决此问题。

    Fruit = Backbone.Model.extend({
        url: "/fruits:id",
        initialize: function initialize () {
            this.set('isWashed', false);
            return this.fetch();
        }
    });
    
    Apple = Fruit.extend({
        url: "/fruits/apples:id"
        initialize: function initialize () {
                var that = this;
            Fruit.prototype.initialize.call(this, arguments).then(function(){
                that.fetch();
            })
            this.set("hasSeed", true);
        }
    });
    

    现在您的Apple 模型确实具有Fruit 的所有属性。

    关键行是Fruit.prototype.initialize.call(this, arguments);。你为Apple调用Fruit的初始化方法。

    您也可以使用this.__super__ 访问父模型:

    this.__super__.prototype.initialize.call(this, arguments);

    【讨论】:

    • 一些事情:在上面的代码中,Apple 中的 initialize 方法由于某种原因永远不会被调用。但除了这个问题,我还如何获取子类特定的属性?
    • @adekom 我更新了我的答案。您必须异步获取父模型和子模型。
    • 谢谢,这让我走上了正轨。我在上面发布了我的实际实现。
    • 由于此解决方案而弹出的一个相关问题:在 Apple 中调用 this.model.toJSON() 只会返回 Fruit 中设置的那些属性。我将如何克服这个问题?
    • 您可以覆盖toJSON。让它调用 fetch,返回一个 Promise 并在 fetch 成功时用 Backbone.Model.toJSON 解决这个 Promise。您的 toJSON 将不再返回非标准的裸对象。但是 Backbone 不是为异步编程而设计的。
    猜你喜欢
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多