«10 $ digest () итераций достигнуто», когда ng-repeat список из функции контроллера директивы

0

Я пытаюсь создать директиву, которая будет отображать данные. Отображение данных включает в себя простой синтаксический анализ, который я ввел в функции контроллера. При запуске этого я получил позорную 10 $digest() iteration reached ошибки, но не могу понять, почему.

Я выделил все в этот простой plnkr: http://plnkr.co/edit/D8X9AmfDPdbvQDr4ENBR?p=preview

Может кто-то сказать:

  • Почему это происходит только тогда, когда я использую ng-repeat для повторения результатов функции getList(), но не тогда, когда я просто печатаю его?
  • Почему это происходит только при возврате массива из getList(), но не при возврате объекта?
  • Почему это происходит только тогда, когда список возвращается из getList(), но работает тот же список, просто статический в контроллере?

Должен сказать, я здесь смущен...

Теги:
angularjs-directive

1 ответ

1

Выполнение return [...]; каждый раз создает новый массив. Затем ng-repeat считает, что наблюдаемое выражение изменилось и запускает другой цикл дайджеста... который вызывает getList() снова, возвращает новый массив, запускает и так далее.

Я думал, что использование track by в выражении ng-repeat поможет, но это не так. Кажется, что track by может связывать новую версию объектов внутри массива, но не изменения в самом массиве.

Единственный способ - убедиться, что каждый раз возвращаете одну и ту же ссылку на массив. Например:

controller: function($scope) {
    var list = [];

    $scope.getList = function() {
        return list;
    };

    $scope.fetchList = function() {
        // You would need a way to fill the list. Can of course be done in
        // the initializer, i.e. 'var list = [{x:1, y:2}]', but this is a trivial
        // case; you probably want to call a service and fill the list.
        ...
    };

    $scope.removeFromList = function(item) {
        // also remember *not* to change the reference when manipulating the list,
        // e.g. removing items: do it in place with 'splice()', 'push()' etc
        var index = list.indexOf(item);
        if( index >= 0 ) {
            list.splice(index, 1);
        }
    };
}

В любом случае использование track by имеет свои достоинства, поэтому рассмотрите его, но это не имеет отношения к этой проблеме.

  • 0
    Спасибо! это объясняет вещи. Что мне делать, если list является переменной области действия в директиве, исходящей от родительского контроллера, и для ее загрузки требуется время? Согласно тому, что вы сказали, я хочу выполнить весь анализ, когда $ scope.list получает новое значение, и сохранить его в контроллере директивы, но кажется, что я не получаю уведомление, когда родитель изменяет список. Это отражается в шаблоне, но link () больше не вызывается.
  • 0
    Из того, что вы говорите, вы, вероятно, должны добавить часы - это также может быть watchCollection . Но это слишком абстрактно, лучше предоставить код.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню