我知道我可以捕获输入框上的keydown事件,并从处理程序返回false,以阻止将按键应用于输入框。我想在更高的级别上使用敲除绑定来做一些事情,例如,我想阻止即将发生的更新,比如,在检查输入框中输入的值是否非法后,我不希望非法值应用到我的视图模型中,然后我不得不“手动”撤销它。我希望在视图模型以任何方式更改之前停止它。
我遇到的另一个真实的用例是,我想在输入应用到视图模型之前更改它的某些内容。例如,我可能想在更新它之前保存当前状态的副本。
如何在knockout框架中实现这一点呢?我可以处理mounsedown或focus事件,准备保存值,然后让更新发生,如果需要,再撤消更新,但我想停止更新本身。
下面是我的尝试:
<html>
<head>
<title>Initial Write Protect Example</title>
<script src="knockout-3.5.0.debug.js" type="text/javascript"></script>
<script type="text/javascript">
const data = {
value: ko.computed({
owner: this,
read: function() { return "foo"; },
write: function(x) { console.log("writing: " + x); debugger; }
}),
};
let allowKey = true;
const changeFn = function(x) { console.log("changed: ", x, data.value()); debugger; return false; };
const beforeChangeFn = function(x) { console.log("about to change: ", x, data.value()); debugger; return false; };
const keydownFn = function(x,event) { console.log("keydown: " + event.key + " allow? " + allowKey); return allowKey; };
const keyupFn = function(x,event) { console.log("keyupn: " + event.key); return false; };
</script>
</head>
<body>
<p>
<span>Current Value:</span>
<span data-bind="text: value"></span>
<br/>
<input data-bind="value: value,
event:{
change: changeFn,
beforeChange: beforeChangeFn,
keydown: keydownFn,
keyup: keyupFn
}"></input>
</p>
<script type="text/javascript">ko.applyBindings(data);</script>
</body>
</html>
从这里可以清楚地看到,虽然我可以阻止一个键生效(在调试器中将allowKey设置为false),但我无法阻止更改,没有发送beforeChange事件(在ko源代码中提到过一次,所以我想我应该尝试一下),并且change事件在ko.observable写入之后出现。所以,太晚了,当change事件触发时视图模型已经更改了。
我想我可以进入淘汰赛源代码来为自己修复一个很好的beforeChange事件,该事件的返回值为false将停止进一步的处理(并实际上将输入框中的值恢复为以前的值)。但我想知道是否已经有一些方法可以替代它?
更新:
现在我已经了解到,可以为一个可观察对象订阅beforeChange事件:
observable.subscribe((newValue, eventName) => handle(newValue, eventName, 'beforeChange');
我在这里明确地给出了两个参数,以指出新值在这些处理程序中不可用。这是一个遗憾,因为我也需要新值。
1条答案
按热度按时间ffvjumwh1#
下面介绍如何使用可写计算来防止更新传播到源可观察对象。
你可以使用一个扩展器来使它更容易重用。我写了一个扩展器来接受一个 predicate 函数,它接受一个字符串并返回true或false。根据你想用它做什么,你可能想支持一个 predicate ,它接受
prevValue
和nextValue
。这将导致validator(target(), str)
。注意:如果输入字段没有响应,可能会给用户带来不好的体验,因此请确保向在输入字段中键入内容的用户提供反馈。
第一个