确定此AngularJs错误$ rootScope:infdig的来源

时间:2015-06-24 23:14:17

标签: angularjs

好的,我很难弄清楚造成这个错误的原因。我想这可能是由于我的routeOrderValidator指令中有一块手表,但我无法看到我在哪里修改手表值。 :(

这是我的Plunker,可以通过输入" 3"来重现错误。进入 John Smith 审核者的路由顺序字段。

这是我的指令代码:

(function () {
    'use strict';

    angular
      .module('app')
      .directive('routeOrderValidator', routeOrderValidator);

    routeOrderValidator.$inject = ['$filter'];

    function routeOrderValidator($filter) {

        var directive = {
            require: 'ngModel',
            link: link,
            restrict: 'A'
        };

        return directive;

        function link(scope, element, attrs, ngModel) {

            scope.$watch(attrs.routeOrderValidator, function () {
                ngModel.$validate();
            }, true);

            ngModel.$validators.routeOrder = function (modelValue, viewValue) {

                return validate(scope, element, attrs, ngModel, modelValue, viewValue);
            };
        }

        function validate(scope, element, attrs, ngModel, modelValue, viewValue) {


            var isValid = true;

            var reviewers = scope.$eval(attrs.routeOrderValidator);

            if (!reviewers) {
                return isValid;
            }

            var sorted = $filter('orderBy')(reviewers, 'route');

            var i, len, count = 0;

            for (i = 0, len = sorted.length; i < len; i++) {
                if (sorted[i].office == 'Branch') {
                    count++;
                }
            }

            for (i = 0, len = sorted.length; i < len; i++) {

                if (count > 0) {
                    if (sorted[i].office == 'Branch') {
                        count--;
                    } else {
                        isValid = false;
                        break;
                    }
                }
            }

            return isValid;
        }
    }

})();

这是我的控制器代码:

(function() {
  'use strict';

  angular
    .module('app')
    .controller('controller1', controller1);

  controller1.$inject = ['$location'];

  function controller1($location) {

    var data = {
      'title': 'More Snacks Please',
      'description': 'Add beef jerky to the breakroom snacks.',
      'reviewers': [{
        'name': 'John Smith',
        'office': 'Branch',
        'route': '1'
      }, {
        'name': 'Amy Jones',
        'office': 'Corporate',
        'route': '2'
      }, {
        'name': 'Foo Bar',
        'office': 'Corporate',
        'route': '3'
      }]
    };

    var vm = this;
    vm.data = data;

  }
})();

这是我的HTML:

    <form name="form1">
    <label>
        Title:
        <input type="text" name="title" ng-model="vm.data.title" />
    </label>
    <label>
        Description:
        <textarea type="text" name="description" ng-model="vm.data.description"></textarea>
    </label>
    <h3>Reviewers</h3>
    <ul ng-repeat="reviewer in vm.data.reviewers">
        <li>
            <label>
                Name:
                <input type="text" name="name_{{$index}}" ng-model="reviewer.name" />
            </label>
            <label>
                Office:
                <select name="office_{{$index}}" ng-model="reviewer.office">
                    <option>Branch</option>
                    <option>Corporate</option>
                </select>
            </label>
            <label>
                Routing Order:
                <input type="text"
                       name="route_{{$index}}"
                       ng-model="reviewer.route"
                       route-order-validator="vm.data.reviewers" />
            </label>
            <p ng-show="form1.route_{{$index}}.$error.routeOrder" class="error">Branch employees must be first in the routing order!</p>
        </li>
    </ul>
</form>

1 个答案:

答案 0 :(得分:1)

你遇到的问题是$ validator会删除错误的对象/属性,如果它无效。

示例: 当John Smith的路由顺序为3时,路由属性将被删除,因为它无效。

这会导致$ watch被触发,因为对象已经被更改并导致无限循环。

可能的解决方案之一是避免ngModel.validate(),直到所有其他验证完成(即验证单个路由顺序)

来自:

   scope.$watch(attrs.routeOrderValidator, function () {
            ngModel.$validate();
        }, true);

致:

    scope.$watch(attrs.routeOrderValidator, function () {
          if(ngModel.$valid )
          {
              ngModel.$validate();}
        }, true);