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 элемента div со вставленным словом newtext.

Если я изменю свой объект параметров так, чтобы он не использовал вложение, а поместил все параметры на верхний уровень, у меня не возникнет проблем.

Таким образом, может показаться, что canJS неправильно объединяет вложенные объекты при объединении параметров со значениями по умолчанию. Так ли это? Есть ли у кого-нибудь умные идеи, как я мог бы поддерживать эту функцию без разветвления? Или я упускаю что-то очевидное? Это избавило бы меня от необходимости писать много трудоемкого кода для создания опций, если бы я мог это сделать.


person AndyFlan    schedule 18.09.2013    source источник
comment
кажется, что can.js в какой-то момент объединяет значения по умолчанию с параметрами экземпляра, но не делает глубокую копию. если вы можете получить доступ к объекту по умолчанию из своей функции инициализации, вы можете сделать эту глубокую придурку самостоятельно или использовать ее напрямую   -  person tikider    schedule 18.09.2013


Ответы (1)


Как указал @tikider, can.extend использует собственные библиотеки .extend (в большинстве случаев, вероятно, $.extend), которые по умолчанию не выполняют глубокое клонирование. Однако вы должны иметь возможность перезаписать настройку элементов управления и сделать глубокое расширение :

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);
    }
});
person Daff    schedule 18.09.2013