1

両方のフィールドが入力された後に検証する必要がある 2 つの入力フィールドがあります。クレジットカードの有効期限なので、monthとがありyearます。実際に検証を行うためにサードパーティのサービスを使用しています。

したがって、expexpMonth、およびの 3 つのディレクティブをセットアップしますexpYear

を使用し$watchてユーザー入力を検証しますが、検証が false の場合はエラーを表示したいと思います。を使おうとするng-classexampleForm.$error.expiryError: [$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);
              };
            };
          };

        }]);
4

1 に答える 1

1

問題は、次の行で妥当性エラーを jquery の選択に設定していることです。

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

次に、次の場合にその jQuery 要素を監視していng-classます。

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

あなたのマークアップで。これにより、angular がこの値をディープ コピーしようとすると、奇妙な例外がスローされます。

.length代わりに、jQuery オブジェクトのプロパティを使用するように変更してください。0 以外 (true) の場合、is-invalidクラスは正しく設定されますが、それ以外の場合は正しく設定されません。

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

あなた...expiry.length > 0と、あなたのコードを調べなければならない将来の開発者にとって、それがより理にかなっている場合は、それを行うこともできます。

この変更で動作するように、Plunkrをフォークしました。

于 2015-07-21T08:41:43.350 に答える