我们说我有类似<input type="text" data-bind="format: quantity">
的内容,它使用名为bindingHandlers
的自定义format
定义如下:
var getElementValue = function($element) {
return $element.val().replace(/\$/g, '');
};
ko.bindingHandlers.format = {
init: function(element, bindingAccessor) {
var $element = $(element),
bindings = bindingAccessor();
$element.val('$' + ko.unwrap(bindings));
$element.change(function () {
bindings(getElementValue($element));
});
},
update: function(element, bindingAccessor) {
var $element = $(element),
bindings = bindingAccessor();
$element.val('$' + ko.unwrap(bindings));
}
};
和视图模型一样:
var ViewModel = function() {
var self = this;
self._quantity = ko.observable(0);
self.quantity = ko.computed({
read: self._quantity,
write: function(newValue) {
if (newValue < 0) {
self._quantity.valueHasMutated();
console.log('quantity is invalid');
return;
}
self._quantity(newValue);
}
});
}
由于不允许负数,因此如果提供了输入,则可以将输入恢复为之前的值。
但是,self._quantity.valueHasMutated();
函数中的write
未通知bindingHandlers
update
突变。
有什么想法吗?我有JSFiddle setup for more details。
答案 0 :(得分:0)
我并不完全确定为什么你的代码无法正常工作,但我确实尝试了一些东西并想出了一些可以做到的事情......
由于您的输入已绑定到quantity
,因此发送此值已更改的消息是有意义的。您可以通过在计算机上调用notifySubscribers
来执行此操作:
self.quantity.notifySubscribers(self.quantity.peek());
这仍然感觉有点奇怪,我建议调查像these examples中那样的扩展器。
这是一个更新的小提琴:http://jsfiddle.net/pxxnuu2z/
答案 1 :(得分:0)
最简单的解决方案是通过对两者使用.extend({ notify: 'always' })
,使用“备份”可观察对象来计算以反映更改时,告诉knockout对旧更改和新值的变化作出反应在文本输入中:
self._quantity = ko.observable(0).extend({ notify: 'always' });
self.quantity = ko.computed({
read: self._quantity,
write: function(newValue) {
if (newValue < 0) {
self._quantity(self._quantity.peek());
//self._quantity.valueHasMutated();
console.log('quantity is invalid');
return;
}
self._quantity(newValue);
}
}).extend({ notify: 'always' });
小提琴:http://jsfiddle.net/k0deqt8x/
编辑:
BTW,此解决方案在使用ko.options.deferUpdates = true;
或者,您可以使用更为标准的解决方案,例如rniemeyer在此创建的解决方案:http://www.knockmeout.net/2011/03/guard-your-model-accept-or-cancel-edits.html