【问题标题】:Angular filter returning an array of objects causing infinite $digest loop角度过滤器返回导致无限 $digest 循环的对象数组
【发布时间】:2014-10-30 18:18:18
【问题描述】:

我有一个自定义过滤器,它返回一个匹配的数组以搜索字段输入并且它可以工作,但只有在导致无限 $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 获得。谢谢!

【问题讨论】:

  • 你能把使用这个过滤器的代码贴出来吗?
  • 我认为是因为angular.copy(object)。每次摘要循环运行时,过滤器都会返回一个 angular 从未见过的新对象数组,因此摘要循环会一直持续下去。
  • @AnthonyChu 谢谢!你对我如何重构这个函数以避免这个问题有什么建议吗?
  • @Prasad 它是用 Slim 编写的,由于 Angular 语法,当我尝试转换为 HTML 时,我不断收到解析器错误,所以不幸的是,查看上下文的最简单方法是点击我发布的链接检查成绩单元素。

标签: angularjs angularjs-directive infinite-loop


【解决方案1】:

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

一种解决方案是返回一个包含与过滤器匹配的原始项目的数组,并为每个项目添加一个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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 2014-02-01
    • 2015-08-02
    • 1970-01-01
    相关资源
    最近更新 更多