37

我想把这个作为这个答案的一个问题,但我似乎不能这样做,我很抱歉。

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

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

这输出:

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

不是我(我认为也不是op)想要的:

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

7 回答 7

50

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

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

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

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

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

或者

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

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

于 2011-07-01T15:48:56.760 回答
18

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

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

看这个例子:

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

于 2011-12-13T17:28:11.447 回答
3

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

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

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

于 2013-05-20T03:33:42.160 回答
0

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

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

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

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

于 2011-07-01T15:41:59.650 回答
0
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
    }
});
于 2014-04-28T14:51:15.500 回答
0

我认为 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()));

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

于 2014-11-14T07:22:16.277 回答
0

另一种方法是使用下划线的_.extend功能来完成此操作:

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

var SubClass = SuperClass.extend({
  defaults: _.extend({
    prop1: val,
    prop2: val2
  }, SuperClass.prototype.baseDefaults)
})
于 2015-10-25T23:33:15.307 回答