我怎样才能得到Knockout JS数据绑定在按键而不是失去焦点?
这个淘汰赛js的例子,所以当你编辑一个字段,然后按TAB,视图模型数据,因此在字段下面的文本被更新。
我怎样才能改变这个代码,以便每个按键更新视图模型数据?
<!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应该使用哪个浏览器事件来检测更改。 以下string值是最常用的选项:
“更改”(默认) – 更新您的视图模型,当用户将焦点移动到不同的控件,或在元素的情况下,立即改变
“keyup” – 在用户释放密钥时更新视图模型
“按键” – 当用户键入一个键时更新你的视图模型。 与keyup不同,当用户按下某个键时,会重复更新
- “afterkeydown” – 只要用户开始input字符,就更新您的视图模型。 这通过捕获浏览器的keydown事件和asynchronous处理事件来工作。
在这些选项中,如果想要实时更新视图模型,“afterkeydown”是最好的select。
在3.2版本中,您可以简单地使用textinput绑定。 :
<input data-bind="textInput: userName" />
它有两个重要的事情:
- 立即更新
- 处理剪切,拖动,自动完成的浏览器差异…
所以不需要额外的模块,自定义控件和其他东西。
如果您希望它在默认情况下在afterkeydown
上执行更新, afterkeydown
可以在value
绑定处理程序中注入valueUpdate
绑定。 只需要提供一个新的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':... };
演示
像这样的解决scheme将适用于Knockout版本2.x。 Knockout团队通过Knockout版本3及以上版本的textInput绑定,充实了对文本类input的更完整绑定。 它被devise为处理文本input和textarea
所有文本input方法。 它甚至会处理实时更新,这有效地使这种方法过时。
杰夫·梅尔卡多的回答非常好,但不幸的是被淘汰赛3淘汰。
但是我通过Knockout 3的变化find了ko开发人员提出的答案。 请参阅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现在有一个更完整的解决scheme,新的“textInput”绑定。 请参阅SalvidorDali的答案