javascript 在 Backbone.js 中扩展模型超类的默认值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6549149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 21:03:14  来源:igfitidea点击:

Extending the defaults of a Model superclass in Backbone.js

javascriptbackbone.jsprototypal-inheritance

提问by mcdoh

I would like to pose this as a question to thisanswer but I can't seem to do so, I apologize.

我想将此作为这个答案的问题,但我似乎无法这样做,我深表歉意。

Extending the defaults for the subclass are reflected in the superclass. This seems to defeat the purpose and I'm more apt to explicitly list the superclass' defaults in the subclass to get the structure I'm looking for.

扩展子类的默认值反映在超类中。这似乎违背了目的,我更倾向于在子类中明确列出超类的默认值以获得我正在寻找的结构。

var Inventory = Backbone.Model.extend({
    defaults: {
        cat: 3,
        dog: 5
    }
});

var ExtendedInventory = Inventory.extend({
});

_.extend(ExtendedInventory.prototype.defaults, {rabbit: 25});

var i = new Inventory();
var ei = new ExtendedInventory();
console.log(i.attributes);
console.log(ei.attributes);

This outputs:

这输出:

{cat: 3, dog: 5, rabbit: 25}
{cat: 3, dog: 5, rabbit: 25}

Not what I (nor, I assume, the op) want:

不是我(也不是我假设的op)想要的:

{cat: 3, dog: 5}
{cat: 3, dog: 5, rabbit: 25}

回答by JCorcuera

The problem is that Inventory.prototype.defaultsand Extended.prototype.defaultshas the same reference, because you have not override the reference.

问题是Inventory.prototype.defaultsExtended.prototype.defaults具有相同的引用,因为您没有覆盖引用。

So you can do this in 2 ways, maybe more but i only found this 2:

所以你可以通过两种方式做到这一点,也许更多,但我只找到了这两种:

Edit:The first example is incorrect (see comments); please refer to the second.

编辑:第一个例子不正确(见评论);请参考第二个。

var ExtendedInventory = Inventory.extend({
    defaults: {
        rabit:25
    }
});

_.extend(ExtendedInventory.prototype.defaults, Inventory.prototype.defaults);

or

或者

var ExtendedInventory = Inventory.extend({
    defaults: _.extend({},Inventory.prototype.defaults,
         {rabit:25}
    )
});

I think the first looks cleaner.

我认为第一个看起来更干净。

回答by b73

I think the best way to solve it is to use underscore.js's _.defaults method. This will allow you to override default values in your Model subclass:

我认为解决它的最好方法是使用 underscore.js 的 _.defaults 方法。这将允许您覆盖模型子类中的默认值:

_.defaults(ExtendedInventory.prototype.defaults, 
           Inventory.prototype.defaults);

See this example:

看这个例子:

http://jsfiddle.net/mattfreer/xLK5D/

http://jsfiddle.net/mattfreer/xLK5D/

回答by ErichBSchulz

As an extension of JCorcuera's answer, if your base class uses (or may use) a function to define defaults then this will work nicely:

作为 JCorcuera 答案的扩展,如果您的基类使用(或可能使用)一个函数来定义默认值,那么这将很好地工作:

   defaults: function() {                                     
     return _.extend( _.result(Slot.prototype, 'defaults'),{  
       kind_id: 6,                                  
       otherthing: 'yello'  
       // add in your extended defaults here                                
   })}                                                      

the key bit being the use of a funciton in the child defaults method and _.result()docs

关键是在子默认方法和文档中使用函数_.result()

回答by Oleksandr Knyga

var MoveToolModel = ToolModel.extend({
    extendDefaults: {
        cursor: 'move'
    },
    initialize: function() {
        ToolModel.prototype.initialize.apply(this, arguments);
        this.defaults = _.extend({}, this.defaults, this.extendDefaults);
    },
    draw: function(canvasContext, data) {
        //drag
    }
});

回答by sanji_san

I think underscore.js don't extend values deeply. You should use Jquery $.extend if you have some array. You can try it here

我认为 underscore.js 不会深入扩展值。如果你有一些数组,你应该使用 Jquery $.extend。你可以在这里试试

var basemodel = Backbone.Model.extend({
  defaults:{a:{"1":"1","2":4,"4":5},b:2}
}
);

var model1 = basemodel.extend({
    defaults: $.extend(false,basemodel.prototype.defaults,{a:{"1":1,"2":2},b:{"xx":13}})
});


var model2 = basemodel.extend({
    defaults: $.extend(false,basemodel.prototype.defaults,{a:{"1":1,"2":2},z:13})
});



var m1 = new model1();
var m2 = new model2();


alert(JSON.stringify(m1.toJSON()));
alert(JSON.stringify(m2.toJSON()));

Also you should give first parameter "false" to do your work correctly. when it is true, just interlace each other.

此外,您应该给第一个参数“false”以正确完成您的工作。当它是真的时,只是相互交织。

回答by dipole_moment

Yet another way is to use underscore's _.extendfunction to accomplish this:

另一种方法是使用 underscore 的_.extend函数来完成此操作:

var SuperClass = Backbone.Model.extend({
  baseDefaults: {
    baseProp1: val,
    baseProp2: val2
  }
});

var SubClass = SuperClass.extend({
  defaults: _.extend({
    prop1: val,
    prop2: val2
  }, SuperClass.prototype.baseDefaults)
})

回答by c3rin

I think you're right that you'd want to make sure that Inventory.prototype.defaults doesn't change as a result of adding rabbit to the ExtendedInventory.defaults. My protoypical inheritance isn't good enough to clearly explain why the below works, but I think this does what you want it to do.

我认为你是对的,你想确保 Inventory.prototype.defaults 不会因为将 rabbit 添加到 ExtendedInventory.defaults 而改变。我的原型继承不足以清楚地解释为什么下面的工作,但我认为这做你想要它做的。

ExtendedInventory.defaults = {}
_.extend(ExtendedInventory.defaults, ExtendedInventory.prototype.defaults, {rabbit: 25});

An important point to remember about the _.extend method is that the first argument is destination. It takes all the attributes from the arguments after the first argument and places them into the destination argument.

关于 _.extend 方法要记住的重要一点是第一个参数是destination. 它从第一个参数之后的参数中获取所有属性,并将它们放入目标参数中。

Another point is that ExtendedInventory.prototype.defaults === Inventory.prototype.defaults results in true, meaning they're the same object, so if you change the prototype of ExtendedInventory you change the prototype of Inventory (I'm not sure why they're equal though in the first place).

另一点是 ExtendedInventory.prototype.defaults === Inventory.prototype.defaults 结果为真,这意味着它们是同一个对象,所以如果你改变 ExtendedInventory 的原型,你就会改变 Inventory 的原型(我不知道为什么尽管首先它们是平等的)。