在事件之后敲除JS textInput

时间:2014-12-02 16:17:33

标签: javascript jquery knockout.js

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

$("#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更新视图模型后的任何想法?

2 个答案:

答案 0 :(得分:1)

有趣的是,模型值的更新需要很长时间并且在游戏中设置得太晚。我查看了textInput绑定源,发现当输入更改时,knockout将值的设置延迟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);
        }
    };

答案 1 :(得分:0)

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

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/