【问题标题】:Knockout JS textInput after event事件后淘汰JS textInput
【发布时间】:2014-12-03 07:15:40
【问题描述】:

我在使用带有自定义自动完成/下拉功能的 textInput 绑定时遇到问题。我正在使用 textInput 绑定,所以我确实看到视图模型得到了更新,但是更新发生在按键事件之后,这也是我的自动完成绑定的事件。这是我的自动完成功能:

$("#table-body").on("keypress", ".combo", function (e) {
    var item = ko.dataFor(e.target),
        drop = $(".dropdown-menu", this);

    if (item.Name() !== undefined && item.Name().length === 0) {
        $(".input-group-btn", this).removeClass("open");
    } else if (item.Name() !== undefined && item.Name() !== null && item.Name() !== "") {
        drop.children().not(":containsNoCase(" + item.Name() + ")").hide();
        drop.children().filter(":containsNoCase(" + item.Name() + ")").show();
        $(".input-group-btn", this).addClass("open");
    }
});

在上述事件中,当输入第一个字符时,item.Name() 为 null 或空格,然后总是在输入的字符后面 1 个字符。关于如何在 textInput 更新视图模型后更改事件捕获的任何想法?

【问题讨论】:

    标签: javascript jquery knockout.js


    【解决方案1】:

    有趣的是,模型值的更新需要这么长时间并且在游戏中设置得这么晚。我查看了 textInput 绑定源,发现当输入更改时,knout 会将值的设置延迟 4ms。可以解释为什么在处理程序运行时值没有更新?

    var deferUpdateModel = function (event) {
            if (!timeoutHandle) {
                // The elementValueBeforeEvent variable is set *only* during the brief gap between an
                // event firing and the updateModel function running. This allows us to ignore model
                // updates that are from the previous state of the element, usually due to techniques
                // such as rateLimit. Such updates, if not ignored, can cause keystrokes to be lost.
                elementValueBeforeEvent = element.value;
                var handler = DEBUG ? updateModel.bind(element, {type: event.type}) : updateModel;
                timeoutHandle = setTimeout(handler, 4);
            }
        };
    

    【讨论】:

    • 啊,我错过了通过源代码。所以我要么需要超时来解决来自 textInput 的延迟,要么使用 dom 选择器
    • 其实和setTimeout无关。 textInput绑定通常会监听input事件,而这个事件在keypress之后触发:w3.org/TR/DOM-Level-3-Events/#keypress-event-order
    【解决方案2】:

    我会考虑在您的 Name observable 上使用淘汰订阅,而不是手动绑定到 keypress 事件。通过这样做,您可以放心,您拥有最新的价值,而不必担心 1-behind 问题。快速制作了一个小提琴来演示。

    vm.name.subscribe(function(val){
        var name = val,
        drop = $(".dropdown-menu");
    
        if (name !== undefined && name.length === 0) {
             $(".input-group-btn").removeClass("open");
        } else if (name !== undefined && name !== null && name !== "") {
             drop.children().not(":contains(" + name + ")").hide();
             drop.children().filter(":contains(" + name + ")").show();
             $(".input-group-btn").addClass("open");
        }
    });
    

    http://jsfiddle.net/ttz0p33n/

    【讨论】:

    • 问题是我丢失了更新自动完成所需的 DOM 上下文。我试图避免为此编写自定义绑定,因为我需要挂钩其他事件
    • 嗯,这很棘手。按键事件绑定到输入元素的元素是什么?您能否在绑定中评估 $(this).val() 以获取输入的当前文本值?
    • 或者你能找到范围内的输入元素值吗? $("输入", this).val()
    • 是的,这是一个选项,我希望只使用淘汰视图模型并避免数据的查询选择器。如果没有人有其他建议,我会将其标记为答案。
    • 还有一个选项.. 可以将其包装在一个小的超时中。 jsfiddle.net/ttz0p33n/5
    猜你喜欢
    • 2018-02-27
    • 2013-09-24
    • 2013-01-31
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多