如何将淘汰JS敲入Keypress而不是丢失的焦点?
-
10-10-2019 - |
题
这个示例 淘汰JS 当您编辑字段并按下选项卡时,可以进行工作,因此,ViewModel数据以及字段下面的文本已更新。
如何更改此代码,以便每个按键都更新ViewModel数据?
<!doctype html>
<html>
<title>knockout js</title>
<head>
<script type="text/javascript" src="js/knockout-1.1.1.debug.js"></script>
<script type="text/javascript">
window.onload= function() {
var viewModel = {
firstName : ko.observable("Jim"),
lastName : ko.observable("Smith")
};
viewModel.fullName = ko.dependentObservable(function () {
return viewModel.firstName() + " " + viewModel.lastName();
});
ko.applyBindings(viewModel);
}
</script>
</head>
<body>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
</body>
</html>
解决方案
<body>
<p>First name: <input data-bind="value: firstName, valueUpdate: 'afterkeydown'" /></p>
<p>Last name: <input data-bind="value: lastName, valueUpdate: 'afterkeydown'" /></p>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
</body>
来自 文档
其他参数
valueupdate
如果您的绑定还包括一个称为valueupdate的参数,则定义浏览器事件KO应用于检测更改。以下字符串值是最常见的选择:
“更改”(默认) - 当用户将焦点移至其他控件或元素的情况下,在任何更改后立即更新视图模型
“钥匙” - 用户发布键时会更新视图模型
“按键” - 用户输入键后,更新视图模型。与Keyup不同,当用户按住钥匙时,这会反复更新
- “ afterkeydown” - 用户开始键入字符后立即更新视图模型。这是通过捕获浏览器的键盘事件并异步处理事件的方法来起作用。
在这些选项中,如果您想实时保持视图模型更新,则“ AfterKeyDown”是最佳选择。
其他提示
在 版本3.2 您可以简单地使用 textInput绑定。:
<input data-bind="textInput: userName" />
它做两个重要的事情:
- 立即进行更新
- 处理浏览器差异以进行切割,拖动,自动完成...
因此,无需其他模块,自定义控件和其他事项。
如果您希望它进行更新 afterkeydown
“默认情况下,”您可以注入 valueUpdate
在 value
绑定处理程序。只是提供新的 allBindingsAccessor
用于处理程序,其中包括 afterkeydown
.
(function () {
var valueHandler = ko.bindingHandlers.value;
var getInjectValueUpdate = function (allBindingsAccessor) {
var AFTERKEYDOWN = 'afterkeydown';
return function () {
var allBindings = ko.utils.extend({}, allBindingsAccessor()),
valueUpdate = allBindings.valueUpdate;
if (valueUpdate === undefined) {
return ko.utils.extend(allBindings, { valueUpdate: AFTERKEYDOWN });
} else if (typeof valueUpdate === 'string' && valueUpdate !== AFTERKEYDOWN) {
return ko.utils.extend(allBindings, { valueUpdate: [valueUpdate, AFTERKEYDOWN] });
} else if (typeof valueUpdate === 'array' && ko.utils.arrayIndexOf(valueUpdate, AFTERKEYDOWN) === -1) {
valueUpdate = ko.utils.arrayPushAll([AFTERKEYDOWN], valueUpdate);
return ko.utils.extend(allBindings, {valueUpdate: valueUpdate});
}
return allBindings;
};
};
ko.bindingHandlers.value = {
// only needed for init
'init': function (element, valueAccessor, allBindingsAccessor) {
allBindingsAccessor = getInjectValueUpdate(allBindingsAccessor);
return valueHandler.init(element, valueAccessor, allBindingsAccessor);
},
'update': valueHandler.update
};
} ());
如果您不舒服地“覆盖” value
绑定,您可以给出覆盖的自定义绑定不同的名称,并使用该绑定处理程序。
ko.bindingHandlers.realtimeValue = { 'init':..., 'update':... };
这样的解决方案适用于淘汰赛2.x版。淘汰赛团队通过The The The The The Text Like输入充实了更完整的约束力 TextInput 在淘汰赛3及以上绑定。它旨在处理所有文本输入方法的文本输入方法和 textarea
. 。它甚至将处理实时更新,从而有效地使这种方法过时。
Jeff Mercado的回答很棒,但不幸的是,淘汰赛3。
但是我发现KO开发人员在进行淘汰3个更改时提出了答案。请参阅底部评论 https://github.com/knockout/knockout/pull/932. 。他们的代码:
//automatically add valueUpdate="afterkeydown" on every value binding
(function () {
var getInjectValueUpdate = function (allBindings) {
return {
has: function (bindingKey) {
return (bindingKey == 'valueUpdate') || allBindings.has(bindingKey);
},
get: function (bindingKey) {
var binding = allBindings.get(bindingKey);
if (bindingKey == 'valueUpdate') {
binding = binding ? [].concat(binding, 'afterkeydown') : 'afterkeydown';
}
return binding;
}
};
};
var valueInitHandler = ko.bindingHandlers.value.init;
ko.bindingHandlers.value.init = function (element, valueAccessor, allBindings, viewModel, bindingContext) {
return valueInitHandler(element, valueAccessor, getInjectValueUpdate(allBindings), viewModel, bindingContext);
};
}());
http://jsfiddle.net/mbest/gkjnt/
编辑 KO 3.2.0现在具有更完整的解决方案,并具有新的“ TextInput”绑定。请参阅Salvidordali的答案