Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 自定义过期日期指令引发rootScope摘要错误_Javascript_Angularjs_Angularjs Directive_Angularjs Rootscope - Fatal编程技术网

Javascript 自定义过期日期指令引发rootScope摘要错误

Javascript 自定义过期日期指令引发rootScope摘要错误,javascript,angularjs,angularjs-directive,angularjs-rootscope,Javascript,Angularjs,Angularjs Directive,Angularjs Rootscope,我有两个输入字段,需要在输入两个字段后进行验证。这是一个信用卡到期日,所以有一个月和年。我正在使用第三方服务来实际执行验证 因此,我设置了3条指令:exp、expMonth和expYear 我使用$watch验证用户输入-但是如果验证为false,我希望显示一个错误当我尝试使用示例表单执行ng类时,$error.expiry,我得到错误:[$rootScope:infdig]10$digest()迭代次数。 这里是一个演示 view.html <form name='exampleF

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

因此,我设置了3条指令:
exp
expMonth
expYear

我使用
$watch
验证用户输入-但是如果验证为false,我希望显示一个错误当我尝试使用
示例表单执行
ng类时,$error.expiry
,我得到
错误:[$rootScope:infdig]10$digest()迭代次数。

这里是一个演示

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

        }]);
    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);
              };
            };
          };

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

        }]);
    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类
查看jQuery元素,此时您有:

ng-class="{ 'is-invalid' : exampleForm.$error.expiry }"
在您的标记中。这会导致angular尝试深度复制此值时引发奇怪的异常

改为使用jQuery对象的
.length
属性。如果非零(truthy),则
无效
类将正确设置,否则将无法正确设置

ng-class="{ 'is-invalid' : exampleForm.$error.expiry.length }"
如果这对您和将来需要查看代码的开发人员更有意义,您还可以执行
…expiry.length>0


因此,它可以处理此更改。

当您获得无限摘要异常时,它还会记录在控制台中计算的最后一个x watch表达式。你能把名单贴出来吗?此外,如果你能在或其他类似的工具中重现这一点,这将有助于我们进行诊断。其他一些评论:1)你使用的是什么版本的AngularJS?2) 我假设在您的标记中,指令实际上是
exp-month
exp-year
(而不是您使用的驼峰格式)。3) 如果将参数记录到
setValidity()
函数中,您会注意到新值(第一个参数)和旧值(第二个参数)之间的差异吗?添加了一个plunkr。非常感谢你。这很有道理。