我可以在自定义指令中以编程方式应用Angular验证指令吗?

Pro*_*ofK 31 javascript angularjs

我发现html输入有以下几种模式,这适用于电话号码:

<input type="text" ng-model="CellPhoneNumber" required ng-pattern="/^[0-9]+$/" ng-minlength="10" />
Run Code Online (Sandbox Code Playgroud)

我想创建一个自定义指令,无论何时应用,都会告诉Angular应用所有这三个规则,例如:

<input type="text" ng-model="CellPhoneNumber" bk-ng-validation="phoneNumber"/>
Run Code Online (Sandbox Code Playgroud)

然后,我的指令中的代码将找到并调用一个名为的函数phoneNumber,我希望在其中看到类似的函数:

清单1:

function bkNgPhoneNumber(model) {
    // This is purely SPECULATIVE pseudo-code, just to convey an idea.
    model.errors.add(applyMinLength(10, model));
    model.errors.add(applyMaxLength(15, model));
    model.errors.add(applyPattern("/^[0-9]+$/", model));
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢上述方法而不是'为这些规则重写代码,例如:

清单2:

function phoneNumber(model) {
    if (model.length < 10 || model.length > 15) {
        model.errors.add("Must be 10 to 15 chars!");
    }
}
Run Code Online (Sandbox Code Playgroud)

我不想废除所有基于属性的指令,但最好创建一个'宏'指令,它将调用我的清单1代码,该代码将实习调用一组更"微观"的验证.

New*_*Dev 19

一种方法(即应用现有验证器而不再重复编写代码)将添加验证指令的相应属性并强制重新编译.这将要求您的指令具有足够高的优先级,并且也是terminal: true.

app.directive("bkNgValidation", function($compile){
  return {
    priority: 10000,
    terminal: true,
    link: function(scope, element){
      element.attr("ng-required", "true");
      element.attr("ng-minlength", 20);
      element.attr("ng-maxlength", 30);

      // prevent infinite loop
      element.removeAttr("bk-ng-validation");

      $compile(element)(scope);
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

演示


Wal*_*anG 6

如果您使用的是更多验证,则可以创建一个负责识别和验证元素的服务,而不受任何限制.角度的默认指令保持不变.

例:

    module.service('$Validation', ["$compile",function($compile){

        this.validators = {
            'phoneNumber': [['required', 1], ['minlength',6], ['maxlength', 10], ['pattern', /^[0-9]+$/.source]],
            'phoneNumber2Custom': function(value){ 
                return /^[0-9]{6,10}$/.test(value) 
            },
            'userTwitter': function(value){
                return /^@(.+)/.test(value)
            }
            // ...etc... /
        }

        this.add = function(scope, element, attrs, model){
            var name = attrs.bkNgValidation, type;
            if(!(type = this.validators[name])) return;
            else if(angular.isFunction(type)) return (model.$validators[name] = type);

            element.removeAttr("bk-ng-validation");
            angular.forEach(type, function(expr){
                element.attr(expr[0], expr[1])
            });
            $compile(element)(scope)        
        };

    }]).directive('bkNgValidation', ["$Validation", function ($Validation) {
        return {
            require: '?ngModel',
            priority: 1e5,
            link: function(){
                $Validation.add.apply($Validation, arguments);
            }
        }
    }])
Run Code Online (Sandbox Code Playgroud)

演示