Angular过滤器返回一个对象数组,导致无限$ digest循环

时间:2014-09-05 18:30:44

标签: angularjs angularjs-directive infinite-loop

我有一个自定义过滤器,它返回一个匹配数组到搜索字段输入,它可以工作,但只有在导致无限$ digest循环之后。这显然只是在从Angular 1.0.6升级后才开始发生。这是过滤器代码:

angular.module("Directory.searches.filters", [])
.filter('highlightMatches', function() {
  var ary = [];
  return function (obj, matcher) {
    if (matcher && matcher.length) {
      var regex = new RegExp("(\\w*" + matcher + "\\w*)", 'ig');
      ary.length = 0;
      angular.forEach(obj, function (object) {
        if (object.text.match(regex)) {
          ary.push(angular.copy(object));
          ary[ary.length-1].text = object.text.replace(regex, "<em>$1</em>");
        }
      });
      return ary;
    } else  {
      return obj;
    }
  }
});

我在其他地方看到这可能是因为在ng-show中使用过滤器,或者是因为每次检查时返回的数组被解释为一个新数组,但我不知道如何我可以修复任何一个问题。您可以在https://www.popuparchive.com/collections/514/items/4859查看此问题的生成示例,并在https://github.com/PRX/pop-up-archive处获得开源项目。谢谢!

1 个答案:

答案 0 :(得分:0)

这是因为angular.copy(object)而发生的。每次摘要周期运行时,过滤器都会返回一个角度前所未见过的新对象数组,因此摘要循环会一直持续。

一种解决方案是返回一个数组,其中包含与过滤器匹配的原始项目,并为每个项目添加了highlightedText属性...

angular.module("Directory.searches.filters", [])
.filter('highlightMatches', function() {
  return function (items, matcher) {
    if (matcher && matcher.length) {
      var filteredItems = [];
      var regex = new RegExp("(\\w*" + matcher + "\\w*)", 'ig');
      angular.forEach(items, function (item) {
        if (item.text.match(regex)) {
          item.highlightedText = item.text.replace(regex, "<em>$1</em>");
          filteredItems.push(item);
        }
      });
      return filteredItems;
    } else  {
      angular.forEach(items, function (item) {
        item.highlightedText = item.text;
      });
      return items;
    }
  }
});

您可以绑定到highlightedText属性,例如......

<div>
    Results
    <ul>
        <li ng-repeat="item in items | highlightMatches : matcher" ng-bind-html="item.highlightedText"></li>
    </ul>
</div>