问题
I would like to pose this as a question to this answer 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:
{cat: 3, dog: 5}
{cat: 3, dog: 5, rabbit: 25}
回答1:
The problem is that Inventory.prototype.defaults
and Extended.prototype.defaults
has the same reference, because you have not override the reference.
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.
回答2:
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:
_.defaults(ExtendedInventory.prototype.defaults,
Inventory.prototype.defaults);
See this example:
http://jsfiddle.net/mattfreer/xLK5D/
回答3:
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:
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
回答4:
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.
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.
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).
回答5:
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
}
});
回答6:
I think underscore.js don't extend values deeply. You should use Jquery $.extend if you have some array. You can try it here
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.
回答7:
Yet another way is to use underscore's _.extend
function to accomplish this:
var SuperClass = Backbone.Model.extend({
baseDefaults: {
baseProp1: val,
baseProp2: val2
}
});
var SubClass = SuperClass.extend({
defaults: _.extend({
prop1: val,
prop2: val2
}, SuperClass.prototype.baseDefaults)
})
来源:https://stackoverflow.com/questions/6549149/extending-the-defaults-of-a-model-superclass-in-backbone-js