自定义滤镜可生成带角度流星的无限消化循环

时间:2016-06-02 21:59:58

标签: angularjs ecmascript-6 angular-filters angular-meteor

我遇到的问题是,自定义滤镜会在角度流星中产生无限的摘要循环。 (Angular error description page

我在这个plunk中用纯粹的角度做了一个工作的例子。当我尝试使用es6风格的角度流星时,脚本在无限循环中运行。

这是我的控制器

class MyController {
  constructor($scope, $reactive) {
    'ngInject';
    $reactive(this).attach($scope);

    this.items = [{ item: 'item1' }, { item: 'item2' }, { item: 'item3' }, { item: 'item4' }];    
  }
}

这是模板

<div ng-repeat="item in vm.items | testFilter">
  Item: {{item.item}}
</div>

过滤器实现只是制作了原始内容的副本(因此它不会过滤任何内容,但它可以进行演示)。

[...]
.filter('testFilter', () => {
  return (items) => {
    var result = angular.copy(items);
    // maybe splice some elements from result
    return result;
  };
})
[...]

我不明白为什么这在普通的角度工作但不在流星中工作的原因。是因为es6 =&gt; es5翻译?我错过了什么,并以错误的方式使用过滤器?还是我找到了角形流星虫?

我很乐意提供一些建议。 :)

更新

  • 我发现,只有链中的最后一个过滤器会产生此错误。因此,当变量传递给范围时,可能会发生这种情况。
  • 当我在构建目录中检查结果时,ES6 =&gt; ES5翻译对我来说似乎没问题。

1 个答案:

答案 0 :(得分:3)

我为此问题创建了一个通用的解决方法,因此在将现有的角度应用程序迁移到meteor时,自定义过滤器的逻辑在许多情况下都可以保持不变。 (Gist with comments

ClassThatImplementsSomeInterface

它并不真正过滤输入数组的任何元素,而是返回输入的克隆。克隆是每个输入配置的相同实例。这不是一个深刻的克隆。如果输入数组包含对象,则结果数组将包含相同的实例。

用法:

  1. 将此过滤器添加到项目的基本模块中。
  2. 在模板中使用它作为链中应用的最后过滤器:

        .filter('fixLoopFilter', () => {
            const instanceCache = {};
    
            return (items) => {
                const hash = CryptoJS.SHA1(angular.toJson(items)).toString();
                if (!instanceCache[hash]) instanceCache[hash] = [];
                instanceCache[hash].length = 0;
                items.map((item) => {
                    instanceCache[hash].push(item);
                });
                return instanceCache[hash];
            };
        })
    
  3. 缺点:

    对于大型输入数组或大型对象数组,此过滤器可能会消耗性能和内存。它只是作为一个工作量,直到问题得到解决或者有一个更好的解决方法来解决这个问题。