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

Custom expiration date directive throwing rootScope digest error

本文关键字:rootScope 错误 日期 指令 自定义      更新时间:2023-09-26

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

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

我使用$watch来验证用户输入-但是,如果验证为假,我想显示一个错误。当我试图用exampleForm.$error.expiryng-class时,我得到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);
              };
            };
          };
        }]);

问题是,您正在将有效性错误设置为jquery选择的行:

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

当你有:

时,你可以通过ng-class来观察jQuery元素
ng-class="{ 'is-invalid' : exampleForm.$error.expiry }"
标记中的

。当angular试图深度复制这个值时,会抛出奇怪的异常。

改为使用jQuery对象的.length属性。如果非零(true),则is-invalid类将被正确设置,否则将不被正确设置。

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

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

我分叉了你的Plunkr,所以它可以与这个变化。