Расширение стандартных значений суперкласса модели в Backbone.js
Я хотел бы задать это как вопрос к этому, но я не могу этого сделать, прошу прощения.
Расширение значений по умолчанию для подкласса отражается в суперклассе. Похоже, что это превзошло эту цель, и я больше склонен явно перечислять значения по умолчанию для суперкласса в подклассе, чтобы получить структуру, которую я ищу.
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}
Ответы
Ответ 1
Проблема в том, что Inventory.prototype.defaults
и Extended.prototype.defaults
имеют одну и ту же ссылку, потому что вы не переопределили ссылку.
Итак, вы можете сделать это двумя способами, может быть, больше, но я нашел только это 2:
Изменить: Первый пример неверен (см. комментарии); обратитесь ко второму.
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}
)
});
Я думаю, что первый выглядит чище.
Ответ 2
Я думаю, что лучший способ решить это - использовать метод underscore.js _.defaults. Это позволит вам переопределить значения по умолчанию в подклассе Model:
_.defaults(ExtendedInventory.prototype.defaults,
Inventory.prototype.defaults);
См. этот пример:
http://jsfiddle.net/mattfreer/xLK5D/
Ответ 3
Как расширение ответа JCorcuera, если ваш базовый класс использует (или может использовать) функцию для определения значений по умолчанию, то это будет работать красиво:
defaults: function() {
return _.extend( _.result(Slot.prototype, 'defaults'),{
kind_id: 6,
otherthing: 'yello'
// add in your extended defaults here
})}
ключевой бит является использованием funciton в методе дочерних по умолчанию и _.result()
docs
Ответ 4
Я думаю, вы правы, что хотите убедиться, что Inventory.prototype.defaults не изменяется в результате добавления кролика в ExtendedInventory.defaults. Мое протоипическое наследование недостаточно хорошо, чтобы четко объяснить, почему работает ниже, но я думаю, что это делает то, что вы хотите.
ExtendedInventory.defaults = {}
_.extend(ExtendedInventory.defaults, ExtendedInventory.prototype.defaults, {rabbit: 25});
Важным моментом для запоминания метода _.extend является то, что первым аргументом является destination
. Он принимает все атрибуты из аргументов после первого аргумента и помещает их в целевой аргумент.
Другим моментом является то, что ExtendedInventory.prototype.defaults === Inventory.prototype.defaults приводит к истине, то есть они являются одним и тем же объектом, поэтому, если вы измените прототип ExtendedInventory, вы измените прототип Inventory (я не уверены, почему они равны, хотя в первую очередь).
Ответ 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
Я думаю, что 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" для правильной работы. когда это правда, просто чередуйте друг друга.
Ответ 7
Еще один способ - использовать функцию подчеркивания _.extend
для выполнения этого:
var SuperClass = Backbone.Model.extend({
baseDefaults: {
baseProp1: val,
baseProp2: val2
}
});
var SubClass = SuperClass.extend({
defaults: _.extend({
prop1: val,
prop2: val2
}, SuperClass.prototype.baseDefaults)
})