自定义到期日期指令抛出rootScope摘要错误

时间:2015-07-20 23:33:37

标签: javascript angularjs angularjs-directive angularjs-rootscope

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

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

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

以下是演示 http://plnkr.co/edit/SSiSfLB8hEEb4mrdgaoO?p=preview

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

        }]);

1 个答案:

答案 0 :(得分:1)

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

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

然后,当你有:{/ p>时,你正在通过ng-class观看jQuery元素

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

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

而是将其更改为使用jQuery对象的.length属性。如果非零(真实),is-invalid类将被正确设置,否则它将不会。

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

如果您和将来需要查看代码的开发人员更有意义,您也可以...expiry.length > 0

forked your Plunkr因此适用于此更改。