Два элемента управления, связанные с одним и тем же наблюдаемым свойством нокаута, вызывают ошибки

Я пытаюсь написать немного пользовательского интерфейса, который позволяет пользователю либо вводить число через текстовое поле, либо выбирать вариант из раскрывающегося списка.

Я сделал упрощенный jsFiddle по адресу http://jsfiddle.net/unklefolk/PNQeR/2/

Как вы видете:

  • Когда выбрано «Число», вы можете ввести текст в текстовое поле.
  • Когда выбрано «Параметр», вы можете выбрать один из двух вариантов в раскрывающемся списке.

Текстовое поле и раскрывающийся список ОБА привязаны к свойству ItemValue элемента в viewModel. Хотя код работает, я получаю ошибки. Если вы запустите окно отладки в Chrome, при изменении первого раскрывающегося списка вы получите сообщение об ошибке:

Uncaught TypeError: объект 0 не имеет метода «ItemName»

Я считаю, что это происходит в ItemText dependableObservable (также известном как вычисляемый).

    this.ItemText = ko.dependentObservable(function () {
        return _isItemAConstant() === 'true' ? this.ItemValue() : this.ItemValue().ItemName();
    }, this);

Очевидно, что функция ItemName() вызывается для числового значения '0', вызывая ошибку.

Что я могу сделать, чтобы эта ошибка не возникала? Является ли мой дизайн привязки двух элементов управления к одному и тому же наблюдаемому фундаментальной ошибкой?


person Mark Robinson    schedule 28.05.2012    source источник


Ответы (1)


Вы изменяете _isItemAConstant на false перед установкой элемента в объект со свойством ItemName. Как только вы установите его, ваш зависимый Observable запустится и попытается оценить наблюдаемый ItemName(), которого не существует. Вы можете либо проверить наличие свойства ItemName, либо использовать расширитель дроссельной заслонки для задержки вычислений. пока не будут внесены все изменения:

this.ItemText = ko.dependentObservable(function () {
    return _isItemAConstant() === 'true' ? this.ItemValue() : this.ItemValue().ItemName();
}, this).extend( { throttle: 1} );

this.ItemText2 = ko.computed(function() {
    return this.ItemValue().ItemName ? this.ItemValue().ItemName() : this.ItemValue();
}, this);
person Jason Goemaat    schedule 28.05.2012
comment
Отличный материал, Джейсон. Спасибо за вашу помощь. - person Mark Robinson; 29.05.2012