Javascript 聚焦/模糊后强制触发淘汰订阅

Javascript 聚焦/模糊后强制触发淘汰订阅,javascript,knockout.js,Javascript,Knockout.js,我正在开发一个扩展器,它将触发对字段输入的需求。但是,我希望输入字段最初为空,只有在触发初始焦点然后模糊后,如果您没有提供任何字段输入,我才希望在页面上显示任何错误 我发现的问题是: 如果值未更改,则不会触发对可观察对象的手动订阅 如果原始值未更改,则向valueUpdate绑定提供“模糊”等事件也不会触发更改 我试图避免仅仅为了触发验证而编写自定义绑定 假定总是调用computed,但同样是基于显式引用(即UI)或是因为它们引用的可观察对象已更新(由于未更改,因此也不会触发) 我喜欢使用扩展器

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

我发现的问题是:

  • 如果值未更改,则不会触发对可观察对象的手动订阅
  • 如果原始值未更改,则向valueUpdate绑定提供“模糊”等事件也不会触发更改
  • 我试图避免仅仅为了触发验证而编写自定义绑定
  • 假定总是调用computed,但同样是基于显式引用(即UI)或是因为它们引用的可观察对象已更新(由于未更改,因此也不会触发)
  • 我喜欢使用扩展器的想法,而不必使用绑定在UI中显式引用验证。但是,如果它们在没有任何输入的情况下聚焦和模糊,我似乎无法通过空白和触发的初始状态

    有什么建议吗


    与knockout 3.0相比,我通常使用成对的扩展器和自定义绑定来解决这个问题。标准验证场景只希望在输入并离开字段后出现错误。我喜欢这种方法,因为它更容易理解和重用。在这里

    我认为在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;
            }
        })
    };
    
    <input class="inputField" data-bind="validate: email"/>
    
    示例使用

    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;
            }
        })
    };
    
    <input class="inputField" data-bind="validate: email"/>
    

    所以我通常使用成对的扩展器和自定义绑定来解决这个问题。标准验证场景只希望在输入并离开字段后出现错误。我喜欢这种方法,因为它更容易理解和重用。在这里

    我认为在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;
            }
        })
    };
    
    <input class="inputField" data-bind="validate: email"/>
    
    示例使用

    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;
            }
        })
    };
    
    <input class="inputField" data-bind="validate: email"/>
    

    如果您希望一个可观察对象始终通知一个“更改”,即使它没有更改,您可以通过以下方法来实现:


    如果您希望一个可观察对象总是通知一个“更改”,即使它没有更改,您可以通过以下方法来实现:


    Michael-这只是部分正确,我试过了,问题是它仍然需要“写入”,因为文档说明“使用内置的notify extender确保在写入时始终通知observable的订户,即使值相同。”-我需要在它通过dom元素“聚焦”后触发它(即,即使没有提供值,也会触发对模糊的写入)。Michael-我让它工作了。在尝试了notify扩展器之后(再次)思考了notify扩展器,我意识到了我没有尝试过的东西,即“notify”扩展器和“valueUpdate:‘blur’”。这就成功了。因此,我将对您的答案给予肯定,尽管只对了一半。是的,还需要
    valueUpdate
    选项,但您在问题中已经提到了,所以我认为您已经知道如何使用它。
    notify:'always'
    valueUpdate:'blur'
    一起将导致订阅函数调用两次(至少在knockout 3.2.0中),我不建议这样做Michael-这只是部分正确,我尝试过这样做,问题是它仍然需要“写入”,因为文档说明“使用内置的notify extender确保在写入时始终通知observable的订户,即使值相同。”-我需要在它通过dom元素“聚焦”后触发它(即,即使没有提供值也会触发对模糊的写入)。Michael-我让它工作了。在尝试了notify extender(再次)之后,我想到了我没有尝试过的东西,“notify”extender和“valueUpdate:“blur”一起。这就成功了。所以我要给你的答案打分,虽然只对了一半。是的,
    valueUpdate
    选项也是需要的,但是你在你的问题中已经提到了,所以我想你已经知道如何使用它了。
    notify:'always'
    valueUpdate:'blur'
    一起将导致subscribed函数调用两次(至少在敲除3.2.0中),我不建议这样做+1 Tyrsius-感谢这个很好的例子。但是按照说明,我想避免绑定。并不是说它们不太好,而是我在没有必要使用绑定的情况下,已经接近99.9%实现了我想要的目标。实际上,我在没有+1 Tyrsius的情况下工作了。+1 Tyrsius-感谢这个很好的例子。但是按照说明,我不想o避免绑定。并不是说它们不是很好,而是说我在没有必要使用绑定的情况下,99.9%接近于实现我想要的目标。实际上,我在没有绑定的情况下就可以工作了。