can.Control.defaults и параметры слияния
Используя can.js у меня есть этот элемент управления:
var Test_Controller = can.Control({
defaults: {
option1: 'option1',
option2: 'option2',
option3: {
nested1: 'nested1',
nested2: 'nested2',
nested3: 'nested3'
}
}
}, {
init: function() {
if ($(this.element).attr('data-newtext')) {
this.options.option3.nested2 = $(this.element).data('newtext');
}
$(this.element).text(this.options.option3.nested2);
}
});
.. и эта разметка:
<div class="instance1" data-newtext="newtext"></div>
<div class="instance2"></div>
..то, если я создам экземпляры этого элемента управления следующим образом:
var instance1 = new Test_Controller('.instance1', {});
var instance2 = new Test_Controller('.instance2', {});
То, что я ожидал увидеть, это 2 div, один со словом newtext
вставлен, а другой со словом nested2
но то, что я на самом деле вижу, это 2 деления со словом newtext
вставлено.
Если я изменю свой объект параметров так, чтобы он не использовал вложенность, но поместил все параметры на верхний уровень, то у меня нет проблем.
Поэтому может показаться, что canJS неправильно объединяет вложенные объекты при объединении параметров со значениями по умолчанию. Это тот случай? У кого-нибудь есть какие-нибудь умные идеи, как я мог бы поддерживать эту функцию, не разветвляясь? Или я что-то упускаю очевидное? Это избавило бы меня от необходимости писать много трудоемкого кода для создания опций, если бы я мог это сделать.
1 ответ
Как заметил @tikider, can.extend
использует библиотеки.extend (в большинстве случаев, вероятно, $.extend
), который не делает глубокий клон по умолчанию. Однако вы должны быть в состоянии перезаписать настройки Controls и сделать глубокий переход:
var Test_Controller = can.Control({
defaults: {
option1: 'option1',
option2: 'option2',
option3: {
nested1: 'nested1',
nested2: 'nested2',
nested3: 'nested3'
}
}
}, {
setup: function( element, options ) {
var allOptions = $.extend(true, {}, this.constructor.defaults, options);
return can.Control.prototype.setup.call(this, element, allOptions);
},
init: function() {
if (this.element.attr('data-newtext')) {
this.options.option3.nested2 = this.element.data('newtext');
}
this.element.text(this.options.option3.nested2);
}
});