假设我有类似于<input type="text" data-bind="format: quantity">的东西,它使用了一个名为format的自定义bindingHandlers,定义如下:
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。
发布于 2016-06-21 08:18:58
最简单的解决方案是,在旧值和新值相同的情况下,通过将.extend({ notify: 'always' })用于可观察到的“备份”和计算以反映文本输入中的变化,告诉剔除对更改作出反应:
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/
编辑:
顺便说一句,这个解决方案在使用ko.options.deferUpdates = true;时也能工作。
或者,您可以使用更标准的解决方案,比如rniemeyer在这里创建的解决方案:http://www.knockmeout.net/2011/03/guard-your-model-accept-or-cancel-edits.html
发布于 2016-06-21 08:05:36
我不太清楚为什么你的代码不起作用,但我确实尝试了一些东西,并想出了一些方法.
由于您的输入绑定到quantity,所以发送消息说明此值发生了更改是有意义的。您可以通过在计算结果上调用notifySubscribers来做到这一点:
self.quantity.notifySubscribers(self.quantity.peek());这确实让人感到有些奇怪,我建议查看一个扩展程序,比如这些例子中的扩展程序。
这里有一个更新的小提琴:http://jsfiddle.net/pxxnuu2z/
https://stackoverflow.com/questions/37932222
复制相似问题