Angular自定义验证器指令打破其他指令

时间:2013-08-21 07:47:26

标签: validation angularjs angularjs-directive

我正在尝试为输入字段构建一个指令,该指令使用从外部作用域传递的自定义函数进行验证,例如:

HTML:

<input type="text" custom-validator="checkValidity"/>

控制器:

$scope.checkValidity = function(value){
    return $scope.invalidWords.indexOf(value) === -1;
}

我为此创建了一个详细的plunker:http://plnkr.co/edit/H5A5O3?p=preview

验证有效,但它似乎打破了默认指令,在这种情况下,ng-disabled不起作用,我无法访问ng-model中使用的变量!

这是我的指示:

app.directive('customValidator', function() {   
   return {
      require: "ngModel"
    , scope: { customValidator: '='}
    , link: function postLink(scope, elm, attrs, ctrl) {
          var validator = function(value) {
            if(scope.customValidator && scope.customValidator(value)) {
              ctrl.$setValidity('custom-validator', true);
              return value;
            }
            ctrl.$setValidity('custom-validator', false);
            return undefined;
          }
          ctrl.$parsers.unshift(validator);
          ctrl.$formatters.unshift(validator);
        }      
   } 
});

我无法弄清楚出了什么问题,我真的需要帮助!

我应该留在Angular 1.0.7

2 个答案:

答案 0 :(得分:4)

ng-disabled未处理inputB的原因是您正在通过指令创建新范围:

scope: { customValidator: '=' }

要让您的模型inputBinputA处于同一范围,您可以执行以下操作:

app.directive('customValidator', function() {
    return {
        require: "ngModel", 
        scope: false, 
        link: function postLink(scope, elm, attrs, ctrl) {
            var validator = function(value) {
                customValidator = scope[attrs["customValidator"]];  
                if(customValidator(value)) {
                    ctrl.$setValidity('custom-validator', true);
                    return value;
                }
                ctrl.$setValidity('custom-validator', false);
                return undefined;
            }
            ctrl.$parsers.unshift(validator);
            ctrl.$formatters.unshift(validator);
        }   
    }
});

答案 1 :(得分:3)

ng-model并隔离范围don't mix well,因此请遵循@ Codezilla的建议,不要创建新的范围。

但是,我建议使用$ parse,它允许我们在HTML中明确指出我们正在向指令传递一个带有单个(命名)参数的函数:

<input type="text" ... custom-validator="checkValidity(val)">

app.directive('customValidator', function($parse) {
    return {
        require: "ngModel", 
        //scope: false, 
        link: function postLink(scope, elm, attrs, ctrl) {
            var validationFn = $parse(attrs.customValidator);
            var validator = function(value) {
                if(validationFn(scope, {val: value})) {
                    ctrl.$setValidity('custom-validator', true);
                    return value;
                }
                ctrl.$setValidity('custom-validator', false);
                return undefined;
            }
            ctrl.$parsers.unshift(validator);
            ctrl.$formatters.unshift(validator);
        }   
    }
});

plunker