【问题标题】:Angular custom validator directive breaking other directivesAngular 自定义验证器指令破坏了其他指令
【发布时间】:2013-08-23 11:39:51
【问题描述】:

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

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

【问题讨论】:

    标签: validation angularjs angularjs-directive


    【解决方案1】:

    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);
            }   
        }
    });
    

    【讨论】:

    • 它会工作但是我无法传递自定义函数。就我而言,我必须为 3 个表单输入使用 3 个不同的函数。我试过transclude: true 但似乎无法解决这个问题...
    • @destegabry 看看我更新后的指令,它使用了attrs
    • +1,但我认为使用 $parse 会更干净一些(见我的回答)。
    • @MarkRajcok 我完全同意你的看法。 +1 :)
    【解决方案2】:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 2014-03-07
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      相关资源
      最近更新 更多