Подтвердить что ты не робот

Расширение стандартных значений суперкласса модели в 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}
4b9b3361

Ответ 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)
})