Подтвердить что ты не робот

Почему Scope. $Apply() вызывает $rootScope. $Digest() вместо этого. $Digest()?

В области AngularJS $apply() вызывается для каждого обработчика событий (события ввода/ввода для директивы ввода, события изменения для выбранной директивы и т.д.) и некоторых других случаях.

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

Было бы интересно узнать обоснование такого решения.

4b9b3361

Ответ 1

Было бы здорово иметь авторов AngularJS, но я считаю, что $digest() нужно вызывать на $rootScope, поскольку изменения, вызванные в ретрансляторе, могут иметь побочные эффекты в других областях (даже $rootScope).

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

Вышеизложенное может показаться немного загадочным, поэтому рассмотрим (немного искусственный) пример со списком элементов:

$scope.items = [{name: 'foo', value:0}, {name: 'bar', value:0}, {name: 'baz', value:0}];

Теперь позвольте использовать ng-Repeat, чтобы отобразить приведенный выше список, и предположим, что нажатие на элемент должно увеличивать значение других элементов (еще раз пример немного искусственен, но здесь дело в том, что действие, инициированное в одна область может иметь побочный эффект в других областях). Это может выглядеть так:

$scope.incOther = function(item) {
        for (var i=0; i<$scope.items.length; i++){
            if ($scope.items[i] !== item){
                $scope.items[i].value++;
            }
        }
    };

Примерная функция будет изменять значения в других областях и AngularJS - для отображения правильных результатов - необходимо оценить наблюдателей в родительских областях (до $rootScope, так как мы не знаем, где был определен объект).

Вот полный jsFiddle, иллюстрирующий это: http://jsfiddle.net/pkozlowski_opensource/Z6e5g/3/

Фактически вышеупомянутый jsFiddle также включает объект в $rootScope, чтобы проиллюстрировать, что оценка наблюдателей действительно должна начинаться с самого верха.