角度自定义验证指令 - 如何正确跳过禁用ng字段?

时间:2014-02-13 04:57:26

标签: javascript angularjs angularjs-directive

我自己做了一个自定义指令,它工作正常,但现在我得到了一个表格,其中有ng-disabled个禁用字段,我相信自setTimeout以来我必须调用ng-disabled函数1}}可能在事后发生,但我不确定我是否正确编码...我的代码是正确的方法吗?我不确定是否有一个特殊的位置来放置setTimeout代码,我甚至不确定它是否正确......但它似乎确实有效...所以有人可以验证和/或者如果需要更新我的代码?

// Angular - custom Directive
directive('myDirective', function($log) {
    return {
        require: "ngModel",
        link: function(scope, elm, attrs, ctrl) {
            validate = function(value) {
                .....
            }

            var validator = function(value) { 
                // invalidate field before doing validation 
                ctrl.$setValidity('validation', false); 

                elm.unbind('keyup').bind(keyup, function() {
                    // make the regular validation of the field value
                    var isValid = validate(value); // call validate method           
                    scope.$apply(ctrl.$setValidity('validation', isValid));            
                });  

                // for the case of field that might be ng-disabled, we should skip validation
                setTimeout(function() {
                    if(elm.attr('disabled')) {
                        ctrl.$setValidity('validation', true); 
                    }
                }, 0);

                return value;     
            };

            // attach the Validator object to the element
            ctrl.$parsers.unshift(validator);
            ctrl.$formatters.unshift(validator);
        }
    };
});


修改
我必须注意,这段代码只是我代码的一小部分,我只采用了它的相关部分,是的,首先看unbind('keyup')没有多大意义,除非你看到真正的代码更像是unbind('keyup').bind(optionEvnt) ...这实际上提供了一个额外的可选功能,即选择要在验证器上使用的事件触发器,并且当我使用blur事件时,默认键盘干扰。在许多表单验证中,我更喜欢使用blur事件,这就是为什么它是一个可选功能。
真正的代码可以在我的Github / Angular-Validation上找到,并且每个人都可以使用...看一看,你可能会非常喜欢在你的代码中使用它:)

2 个答案:

答案 0 :(得分:3)

你似乎有很多不必要的代码,除非我错过了你的实际意图。这应该有用。

// Angular - custom Directive
directives.directive('myDirective', function($log) {
    return {
        require: "ngModel",
        link: function(scope, elm, attrs, ctrl) {

            var validate = function(value) {
                return (value === "valid");
            };

            var validator = function(value) {
                ctrl.$setValidity('validInput', validate(value));
                return value;
            };

            // attach the Validator object to the element
            ctrl.$parsers.unshift(validator);
            ctrl.$formatters.unshift(validator);

            // Observe the disabled attribute
            attrs.$observe("disabled",function(disabled) {
                if(disabled){
                    // Turn off validation when disabled
                    ctrl.$setValidity('validation', true);
                } else {
                    // Re-Validate the input when enabled
                    ctrl.$setValidity('validation', validate(ctrl.$viewValue));
                }
            });

        }
    };
});

答案 1 :(得分:1)

我认为如果你使用angular $timeout而不是javascript的原生setTimeout()你会有更多的运气,因为$timeout让角度知道发生了什么,需要更新什么以及所有这些。但是我认为你想要做的最好的解决方案是观察指令的disabled属性,不需要定时器和间隔:

attrs.$observe("disabled",function(value) {

if(value){

       ctrl.$setValidity('validation', true); 

}else{

       ctrl.$setValidity('validation', false); 

}});