Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我怎样才能让击倒JS在键盘上绑定数据,而不是失去焦点?_Javascript_Knockout.js - Fatal编程技术网

Javascript 我怎样才能让击倒JS在键盘上绑定数据,而不是失去焦点?

Javascript 我怎样才能让击倒JS在键盘上绑定数据,而不是失去焦点?,javascript,knockout.js,Javascript,Knockout.js,此示例非常有效,因此当您编辑字段并按TAB键时,viewmodel数据以及字段下方的文本都会更新 如何更改此代码,以便每次按键时都更新viewmodel数据? 击倒js window.onload=function(){ var viewModel={ 名字:ko.observable(“Jim”), 姓氏:ko.observable(“史密斯”) }; viewModel.fullName=ko.DependentToServable(函数(){ 返回viewModel.firstName

此示例非常有效,因此当您编辑字段并按TAB键时,viewmodel数据以及字段下方的文本都会更新

如何更改此代码,以便每次按键时都更新viewmodel数据?


击倒js
window.onload=function(){
var viewModel={
名字:ko.observable(“Jim”),
姓氏:ko.observable(“史密斯”)
};
viewModel.fullName=ko.DependentToServable(函数(){
返回viewModel.firstName()+“”+viewModel.lastName();
});
应用绑定(视图模型);
}
名字:

姓氏:

你好

名字:

姓氏:

你好

附加参数
  • 价值更新

    如果绑定还包括一个名为valueUpdate的参数,则 定义应使用哪个浏览器事件检测更改。这个 以下字符串值是最常用的选择:

    • “更改”(默认)-当用户 将焦点移动到其他控件,或在 元素,在任何更改后立即

    • “keyup”-在用户释放密钥时更新视图模型

    • “按键”-当用户键入 钥匙与keyup不同的是,此选项在用户持有密钥时重复更新 向下

    • “afterkeydown”-在用户 开始键入字符。这是通过捕捉浏览器的 keydown事件并异步处理该事件
在这些选项中,“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
    };
} ());
如果您不习惯“覆盖”
绑定,可以为覆盖的自定义绑定指定不同的名称并使用该绑定处理程序

ko.bindingHandlers.realtimeValue = { 'init':..., 'update':... };


这样的解决方案适用于淘汰版2.x。敲除团队通过敲除版本3及更高版本中的绑定,为类似文本的输入提供了更完整的绑定。它设计用于处理文本输入和
textarea
的所有文本输入方法。它甚至可以处理实时更新,从而有效地使这种方法过时。

杰夫·梅尔卡多的答案非常棒,但不幸的是,他被淘汰3

但是我发现了ko开发人员建议的答案,同时进行了击倒3的更改。请参阅下面的注释。他们的代码:

//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);
    };
}());

编辑
Ko 3.2.0现在有了一个更完整的解决方案,使用了新的“textInput”绑定。请参阅SalvidorDali在3.2版中的回答,您可以简单地使用:


它做了两件重要的事情:

  • 立即更新
  • 处理剪切、拖动、自动完成的浏览器差异

因此不需要额外的模块、自定义控件和其他东西。

来自knockout.js中的文档://语法“after”表示“在事件发生后异步运行处理程序”//这非常有用,例如,可以捕获“keydown”浏览器更新控件后的事件是否仍有获取值更新的方法:'afterkeydown'为默认值?对于某些输入框,浏览器显示“自动填充”值(如输入字段名为“firstname”)。从自动填充中选择“afterkeydown”不起作用。有什么方法可以捕捉到这一点吗?@Anton除了自动填充值之外,还应该捕捉屏幕上的键盘点击和鼠标粘贴事件。使用
afterkeydown
是一个糟糕的解决方案。此答案的作者,请更新以包括Salvador Dali的答案,从3.2开始添加的textInput是一个更好的解决方案,因为它与移动浏览器具有更好的兼容性(例如自动完成工作更好),这样可以使我的标记更整洁。此外,除了“afterkeydown”,还可以添加“input”和“paste”事件来处理粘贴/拖放操作。在上述解决方案中,我认为“typeof valueUpdated==='array'”需要替换为“Object.prototype.toString.call(valueUpdate)==='[Object array]'。感谢您将答案更新为3.0@在KO 3.2中,你甚至不需要它。这对我们这些在KO3.2上的人来说是非常好的,他们在我们开始的时候不知道TextInput,并且不能更新整个系统中的每个输入!在KO 3.2中,不需要做所有这些变通方法:Salvador是正确的-它在最新版本中自动执行。这非常有效,正是我需要替换整个应用程序中的value:field、valueUpdate:“input change”(输入更改)的地方…)谢谢。当用户单击新HTML5搜索输入字段上的“x”图标并在输入为空的情况下执行操作时,是否有方法捕获事件?
<input data-bind="textInput: userName" />