【问题标题】:AngularJS directive scope property matchingAngularJS 指令范围属性匹配
【发布时间】:2014-09-19 07:39:09
【问题描述】:

我正在尝试编写一个隔离指令,该指令将运行正则表达式来验证某些输入字段。 我希望指令知道根据输入的属性匹配和使用什么正则表达式。

示例输入如下所示。

<input required tabindex="5" regex-validation regex="validationRegex.zipRegex" ng-model="payment.zip" type="text" />

下面是指令中的一个示例,它设置了一个控制器来匹配指令本身。 scope.regex.test 日志未定义。

module.controller('Controller', function($scope) {
    $scope.validationRegex = {
        americanExpressRegex: new RegExp(/^(?!3[47]).*$/),
        cvvRegex: new RegExp(/^[0-9]{3,4}$/),
        currencyRegex: new RegExp(/^[$]?\d{0,18}\.?\d{0,2}$/),
        cityRegex: new RegExp(/^[a-zA-Z]+(?:[\s-][a-zA-Z]+)*$/),
        zipRegex: new RegExp(/^[0-9]{5}(?:-[0-9]{4})?$/),
        phoneRegex: new RegExp(/^(\d(\s|\.|\-)?)?\(?\d{3}\)?(\s|\.|\-)?\d{3}(\s|\.|\-)?\d{4}$/),
        /* jshint ignore:start */
        emailRegex: new RegExp("^[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?$"),
        /* jshint ignore:end */
        numberRegex: new RegExp(/^\d+$/),
        addressRegex: new RegExp(/^[A-Za-z0-9 \-_\.,]{0,55}$/),
        bankAccountRegex: new RegExp(/^[0-9]{1,17}$/),
        routingNumberRegex: new RegExp(/^((0[0-9])|(1[0-2])|(2[1-9])|(3[0-2])|(6[1-9])|(7[0-2])|80)([0-9]{7})$/)
    };
})
    .directive('regexValidation', [function () {
        return {
        scope: { regex: "=" },
        link: function (scope, element) {
            element.bind('change', function () {
                console.log(scope.regex);
                //grab the element we are working with into a jquery element
                var ele = $(element);

                //grab the element value for multiple future use
                var value = ele.val();

                //if we have a value check with regex
                if (value && !**scope.regex.test**(value)) {
                    ele.parent().addClass("error");
                }
                    //this will set the element back to how it was and check to see if all validation is
                    //complete
                else {
                    ele.parent().removeClass("error");
                }
            });
        }
    };
}]);

【问题讨论】:

  • 您觉得我的回答有帮助吗?关于这个主题,您还有什么需要了解的吗?
  • 有助于处理事物的思维方式。但更多的是寻找为什么这个指令范围属性正则表达式不能匹配它在视图中被告知的正确正则表达式......我最终通过将validationRegex对象从控制器拉到指令中并匹配validationRegex来解决这个问题属性名称基于提供的元素的正则表达式属性......
  • 正如我的回答所解释的那样,你会遇到各种各样的问题,因为你以各种可能的方式在 Angular 之外工作。 (绑定更改侦听器,直接从元素中提取值,直接修改类)。那时,Angular 实际上是在与你争夺对事物的控制权,而且肯定不会回应你想要的东西。这就是为什么通常建议停止使用 jQuery 和 Angular 的原因。它提供很少/没有帮助,并鼓励与 Angular 对抗。这现在有意义吗?

标签: javascript angularjs angularjs-directive


【解决方案1】:

摆脱jQuery,永不回头。使用 Angular 会让你更进一步。

Angular 已经在处理输入的变化值并通过管道运行它。您需要使用该管道与值进行交互,而不是附加事件侦听器。

查看ngModelController documentation here.

这个过程我解释了很多more detail and with a demo here.

如果您使用的是最新版本的 Angular,您将为此使用 $validator。对于旧版本,您将使用$parser。与其添加一个类来声明状态,不如使用ngModel 的$error 状态。这是一个帮助您入门的示例。

Live demo

.controller('myCtrl', function($scope) {

  $scope.foo = 'abc';
  // in my example, it's always going to be invalid
  $scope.fooValidity = false;

})

.directive('myDirective', function() {

  var directive = {
    scope: {
      isValid: '=myDirective'
    },
    require: 'ngModel',
    link: function($scope, $element, $attrs, $ngModel) {

      // "whatever" is the property which will be assinged on the ngModel $error object
      $ngModel.$validators.whatever = function(val) {
        // write your validation logic here
        // return true or false for valid / invalid
        return $scope.isValid;
      };

    }
  };

  return directive;

})

;

标记:

<!-- Add the `error` class by using the model's error object -->
<!-- Also note that Anuglar will add a `ng-invalid-whatever` class for you -->
<form name="myForm" ng-class="{error:myForm.fooInput.$error.whatever}">
  <input ng-model="foo" name="fooInput" my-directive="fooValidity">
  <p ng-show="myForm.fooInput.$error.whatever">It's invalid!</p>
</form>

【讨论】:

    【解决方案2】:

    混合使用 Angularjs 和 jQuery 并不是最好的选择。但是您可以在没有 jQuery 的情况下验证您的输入,请在此处查看我的工作演示 http://plnkr.co/edit/UzQ6DZcKYLk3PCHeEJiv?p=preview

    只需将您的模型和正则表达式传递给指令,然后在模型更新时测试您的正则表达式

    app.directive('regexValidation', [
    
      function() {
        return {
          scope: {
            regex: "=",
            model: '=ngModel'
          },
          link: function(scope, element, attr) {
            scope.$watch('model', function(newValue, oldValue) {
    
    
              if (!newValue|| scope.regex.test(newValue)) {
                element.removeClass("error").addClass('valid');
              } else {
                element.addClass("error").removeClass('valid');
              }
            });
          }
        };
      }
    ]);
    

    【讨论】:

    • 斯塔普!?为什么每个人都为此发布疯狂的答案? (其他答案已删除)。
    • 我并不是要苛刻或任何事情。我看到你是新来的,我赞扬你想回答一个问题并提供帮助。我已经在这里发布了一个答案,展示了正确的解决方案,并链接到文档以验证这一点,以及另一篇包含更多信息的帖子。这是这篇文章第二次发布使用不良做法的答案之后我已经发布了解释这一点的答案。
    猜你喜欢
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    相关资源
    最近更新 更多