自定义bindingHandlers没有触发我的输入元素的“值更改”

时间:2013-04-27 16:20:27

标签: knockout.js

我有以下bindingHandlers,它允许我格式化我的日期:

ko.bindingHandlers.dateRW = {
    //dateRW --> the 'read-write' version used both for displaying & updating dates
    init: function (element, valueAccessor, allBindingsAccessor) {
        //handle the field changing
        ko.utils.registerEventHandler(element, "change", function () {
            var observable = valueAccessor();
            var myDate = moment($(element).val(), "DD/MM/YYYY");
            observable(myDate.toDate());
        });
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = valueAccessor();  // 'Mon Sep 10 2012 02:00:00 GMT+0200 (Paris, Madrid (heure d’été))'; 
        var date = (typeof value() !== 'undefined') ? moment(value()) : null;
        var dateFormatted = (date != null) ? date.format('DD/MM/YYYY') : '';
        $(element).val(dateFormatted);
    }
};

使用示例:

<input type="text" data-bind="dateRW: myDate" />

它可以工作,但每当我编辑输入元素时,我需要点击元素的外部(失去焦点)以触发value change。我已经尝试valueUpdate: 'afterkeydown'但它不起作用。我知道valueHasMutated存在,但我不知道是否必须这样做。

感谢。


更新

根据建议,我尝试使用keyup事件。我提醒说,我唯一的目标是“模拟”keyup事件中的值已经改变。

ko.utils.registerEventHandler(element, "keyup", function () {
    observable($(element).val());
});

通过这个实现,问题是对于每个按下的键,将触发bindingHandlers上的update。这通常会导致无效日期。示例:用户将在输入字段中一次输入一个新数据。对于每个数字,触发更新并严格解释输入的新内容。

我也试试这个:

ko.utils.registerEventHandler(element, "keyup", function () {
    observable.notifySubscribers($(element).val());
});

通过这个实现,问题是绑定绑定器上的update将被触发,但重用observable后面的当前值,因为这已经是输入中的值,没有检测到任何更改。

我也尝试使用valueHasMutated,但我总是遇到错误,因为我的dependantObservable没有这个方法。

我的目标是每当用户开始更改日期时显示我的Save changes按钮但是只有当他离开焦点时才会真正更新输入字段中的日期(更改事件) < / p>

1 个答案:

答案 0 :(得分:0)

valueUpdate选项仅适用于value绑定,因此在这种情况下它不会帮助您。

您可能希望同时处理change事件和keyupkeydown等其他事件。

此外,在您的update函数中,调用valueAccessor()会让您恢复您的观察值,而不是它所拥有的值。您可能希望将结果作为函数调用,或使用ko.utils.unwrapObservable实用程序安全地返回observable和non-observable的值。展开observable也会创建一个依赖项,因此对该值进行编程更新将再次触发update函数以更新您的值。