Пользовательские фильтры создают бесконечный цикл дайджеста с угловым метеором

У меня проблема в том, что пользовательские фильтры создают бесконечный цикл дайджеста в angular-meteor. (Страница описания ошибки Angular)

Я сделал рабочий пример в этом plunk с чистым angular. Когда я пытаюсь сделать то же самое с angular-meteor в стиле 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;
  };
})
[...]

Я не понимаю, почему это работает в простом angularjs, но не работает в метеоре. Это из-за перевода es6=>es5? Я что-то упускаю и неправильно использую фильтры? Или я нашел ошибку углового метеора?

Буду рад совету. :)

Обновлять

  • Я выяснил, что эту ошибку выдает только последний фильтр в цепочке. Так может случиться, когда переменная передается в область видимости.
  • Перевод ES6=>ES5 кажется мне подходящим, когда я проверяю результат в каталоге сборки.

person Dave Gööck    schedule 02.06.2016    source источник


Ответы (1)


Я создал общий обходной путь для этой проблемы, поэтому при переносе существующего приложения angular на метеор во многих случаях логика пользовательских фильтров может оставаться нетронутой. (Суть с комментариями)

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

На самом деле он не фильтрует какой-либо элемент входного массива, а возвращает клон ввода. Клон — это один и тот же экземпляр для каждой входной конфигурации. Это не глубокий клон. Если входной массив содержит объекты, результирующий массив будет содержать те же экземпляры.

Применение:

  1. Добавьте этот фильтр в базовый модуль вашего проекта.
  2. Используйте его в своем шаблоне в качестве последнего фильтра, применяемого в цепочке:

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

Недостатки:

Этот фильтр может потреблять много памяти и производительности для большого входного массива или большого массива объектов. Это просто предназначено как обходной путь, пока проблема не будет устранена или не будет найдено лучшее обходное решение для этой проблемы.

person Dave Gööck    schedule 07.06.2016