Knockout.js Расширение привязки значения с помощью перехватчика
Похоже, что это общий подход к санации / проверке / форматированию данных с нокаутом при привязке к полю ввода, при этом создается настраиваемая привязка многократного использования, в которой используется вычисляемая наблюдаемая. Это в основном расширяет привязку значения по умолчанию, чтобы включить перехватчик, который будет форматировать / очищать / проверять ввод перед записью / чтением.
ko.bindingHandlers.amountValue = {
init: function (element, valueAccessor, allBindingsAccessor) {
var underlyingObservable = valueAccessor();
var interceptor = ko.computed({
read: function () {
// this function does get called, but it's return value is not used as the value of the textbox.
// the raw value from the underlyingObservable is still used, no dollar sign added. It seems like
// this read function is completely useless, and isn't used at all
return "$" + underlyingObservable();
},
write: function (newValue) {
var current = underlyingObservable(),
valueToWrite = Math.round(parseFloat(newValue.replace("$", "")) * 100) / 100;
if (valueToWrite !== current) {
// for some reason, if a user enters 20.00000 for example, the value written to the observable
// is 20, but the original value they entered (20.00000) is still shown in the text box.
underlyingObservable(valueToWrite);
} else {
if (newValue !== current.toString())
underlyingObservable.valueHasMutated();
}
}
});
ko.bindingHandlers.value.init(element, function () { return interceptor }, allBindingsAccessor);
},
update: ko.bindingHandlers.value.update
};
Пример jsFiddle: http://jsfiddle.net/6wxb5/1/
Я что-то пропустил? Я видел этот метод повсеместно, но, похоже, он не работает полностью. Функция чтения кажется совершенно бесполезной, так как она совсем не используется.. и в функции записи ввод "23.0000" изменяет записанное значение на 23, но значения текстового поля не обновляются.
1 ответ
Вопрос исходит от update
часть вашей пользовательской привязки. Эта часть обновит поле на основе исходного значения модели. Итак, обработчик событий, прикрепленный в init
отправит новое значение через вычисляемую запись, но обновление поля фактически происходит в update
,
Одним из вариантов является применение привязки значения из вашего init
функционировать и пропустить update
функция как:
ko.bindingHandlers.amountValue = {
init: function (element, valueAccessor, allBindingsAccessor) {
var underlyingObservable = valueAccessor();
var interceptor = ko.computed({
read: function () {
// this function does get called, but it's return value is not used as the value of the textbox.
// the raw value from the underlyingObservable, or the actual value the user entered is used instead, no
// dollar sign added. It seems like this read function is completely useless, and isn't used at all
return "$" + underlyingObservable();
},
write: function (newValue) {
var current = underlyingObservable(),
valueToWrite = Math.round(parseFloat(newValue.replace("$", "")) * 100) / 100;
if (valueToWrite !== current) {
// for some reason, if a user enters 20.00000 for example, the value written to the observable
// is 20, but the original value they entered (20.00000) is still shown in the text box.
underlyingObservable(valueToWrite);
} else {
if (newValue !== current.toString())
underlyingObservable.valueHasMutated();
}
}
});
ko.applyBindingsToNode(element, { value: interceptor });
}
};
Обновленная скрипка: http://jsfiddle.net/rniemeyer/Sr8Ev/