Force Knockout订阅在焦点/模糊后触发

时间:2014-01-10 16:57:23

标签: javascript knockout.js

我正在开发一个扩展器,它将触发对字段输入的要求。但是,我希望输入字段最初是空白的,只有在触发初始焦点然后模糊之后,如果您没有在该字段上提供任何输入,我是否要在页面上显示任何错误。

我发现的问题是:

  1. 如果值未更改,则不会触发对observable的手动订阅
  2. 向valueUpdate绑定提供诸如'blur'之类的事件,如果原始值未更改,则不会触发更改
  3. 我试图避免为了触发验证而编写自定义绑定。
  4. 计算机被认为总是被调用,但是再次基于显式引用(即UI),或者因为它们引用的可观察对象已被更新(因为它没有改变而再次没有被触发)。
  5. 我喜欢使用扩展器的想法,而不必通过使用绑定来明确引用UI中的验证。但我似乎无法通过空白的初始状态并触发,如果他们在没有任何输入的情况下聚焦和模糊。

    有什么建议吗?

    VS。淘汰3.0

2 个答案:

答案 0 :(得分:3)

所以我通常使用配对的扩展器和自定义绑定来解决这个问题。标准验证方案仅在输入和保留字段后才想要错误。我喜欢这种方法,因为它更容易理解和重用。这是a fiddle

我没有看到在UI中引用自定义绑定的问题,即使它暗示了验证。知道绑定的UI是淘汰的标准,并且自定义绑定没有任何错误。鼓励他们!

<强>剂

ko.extenders.isValid = function (target, validator) {
    //Use for tracking whether validation should be used
    //The validate binding will init this on blur, and clear it on focus
    //So that editing the field immediately clears errors
    target.isActive = ko.observable(false);

    if (typeof validator !== 'function') {
        validator = function(value) {
            return value !== undefined && value !== null && value.length > 0;
        };
    }

    target.isValid = ko.computed(function () {
        return validator(target());
    });

    //Just a convienient wrapper to bind against for error displays
    //Will only show errors if validation is active AND invalid
    target.showError = ko.computed(function () {
        //This intentionally does NOT short circuit, to establish dependency
        return target.isActive() & !target.isValid();
    });

    return target;
};

使用示例

var login = {
    //use default validation
    email: ko.observable('').extend({ isValid: true }),
    //Use custom validation function
    password: ko.observable('').extend({
        isValid: function (value) {
            return value.length > 0 && value.length <= passwordMaxLength;
        }
    })
};

<强>装订

//Just activate whatever observable is given to us on first blur
ko.bindingHandlers.validate = {
    init: function (element, valueAccessor) {
        ko.bindingHandlers.value.init.apply(this, arguments); //Wrap value init
        //Active will remain false until we have left the field
        //Starting the input with validation errors is bad
        ko.utils.registerEventHandler(element, 'blur', function() {
            valueAccessor().isActive(true);
        });
        //Validation should turn off while we are in the field
        ko.utils.registerEventHandler(element, 'focus', function() {
            valueAccessor().isActive(false);
        });
    },
    update: ko.bindingHandlers.value.update //just wrap the update binding handler
};

使用示例

<input class="inputField" data-bind="validate: email"/>

答案 1 :(得分:1)

如果您希望observable始终通知“更改”,即使它没有更改,您也可以使用notify extender

myObservable.extend({notify:'always'});