自定义过滤器使用 angular-meteor 生成无限摘要循环

Custom filters produces infinit digest loop with angular-meteor

我遇到了问题,自定义过滤器在 angular-meteor 中产生无限摘要循环。 (Angular error description page)

我在这个 plunk 中用纯 angular 做了一个工作示例。当我尝试使用 es6 风格的 angular-meteor 时,脚本在无限循环中是 运行。

这是我的控制器

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;
  };
})
[...]

我不明白为什么这在普通 angularjs 中有效但在 meteor 中无效。是因为 es6=>es5 翻译吗?我是否遗漏了什么并且以错误的方式使用过滤器?还是我发现了 angular-meteor 错误?

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

更新

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

    .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];
        };
    })

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

用法:

  1. 将此过滤器添加到项目的基础模块中。
  2. 在您的模板中将其用作链中应用的 last 过滤器:

    ng-repeat="vm.items | customFilter | fixLoopFilter"
    

缺点:

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