1

我有 2 个输入字段需要在输入两个字段后进行验证。这是信用卡到期日,所以有一个monthyear。我正在使用第三方服务来实际进行验证。

因此,我设置了 3 个指令:expexpMonthexpYear.

我使用 a$watch来验证用户输入 - 但是如果验证为假,我想显示一个错误。当我尝试处理时ng-classexampleForm.$error.expiry我得到Error: [$rootScope:infdig] 10 $digest() iterations reached.

这是一个演示 http://plnkr.co/edit/SSiSfLB8hEEb4mrdgaoO?p=preview

视图.html

  <form name='exampleForm' novalidate>
    <div class="form-group" ng-class="{ 'is-invalid': exampleForm.$error.expiry }">
       <div class="expiration-wrapper" exp>
          <input type='text' ng-model='data.year' name='year' exp-month />
          <input type='text' ng-model='data.month' name='month' exp-year />
       </div>
    </div>

exp.directive.js

  angular.module('example')
    .directive('exp', ['ThirdPartyValidationService',
      function(ThirdPartyValidationService) {
        return {
          restrict: 'A',
          require: 'exp',
          link: function(scope, element, attrs, ctrl) {
            ctrl.watch();
          },
          controller: function($scope, $element, ThirdPartyValidationService) {
            var self = this;
            var parentForm = $element.inheritedData('$formController');
            var ngModel = {
              year: {},
              month: {}
            };

            var setValidity = function(exp) {
              var expMonth = exp.month;
              var expYear = exp.year;
              var valid = ThirdPartyValidationService.validateExpiry(expMonth, expYear);

              parentForm.$setValidity('expiry', valid, $element);
            };

            self.setMonth(monthCtrl) {
              ngModel.month = monthCtrl;
            };

            self.setYear(yearCtrl) {
              ngModel.year = yearCtrl;
            };

            self.watch = function() {
              $scope.$watch(function() {
                return {
                  month: ngModel.month.$modelValue,
                  year: ngModel.year.$modelValue
                };
              }, setValidity, true);
            };
          }
        };
      }]);

expMonth.directive.js

    angular.module('example')
      .directive('expMonth', [
        function() {
          return {
            restrict: 'A',
            require: ['ngModel', '^?exp'],
            compile: function(element, attributes) {
              return function(scope, element, attributes, controllers) {

                var formCtrl = controllers[0];
                var expMonthCtrl = controllers[1];

                expMonthCtrl.setMonth(formCtrl);
              };
            };
          };

        }]);

expYear.directive.js

    angular.module('example')
      .directive('expYear', [
        function() {
          return {
            restrict: 'A',
            require: ['ngModel', '^?exp'],
            compile: function(element, attributes) {
              return function(scope, element, attributes, controllers) {

                var formCtrl = controllers[0];
                var expYearCtrl = controllers[1];

                expYearCtrl.setYear(formCtrl);
              };
            };
          };

        }]);
4

1 回答 1

1

问题是您正在使用以下行将有效性错误设置为 jquery 选择:

parentForm.$setValidity('expiry', valid, $element);

然后,您可以通过以下方式观看该 jQuery 元素ng-class

ng-class="{ 'is-invalid' : exampleForm.$error.expiry }"

在您的标记中。当 Angular 尝试深度复制该值时,这会导致抛出奇怪的异常。

相反,将其更改为使用.lengthjQuery 对象的属性。如果非零(真),is-invalid类将被正确设置,否则不会。

ng-class="{ 'is-invalid' : exampleForm.$error.expiry.length }"

...expiry.length > 0如果这对您和必须查看您的代码的未来开发人员更有意义,您也可以这样做。

分叉了你的 Plunkr,所以它适用于这个变化。

于 2015-07-21T08:41:43.350 回答