Angular Наблюдение и последовательность событий ng-click

У меня есть этот код внутри директивы angular, и я нахожу поведение $watch немного запутанным. Функция updateSelect вызывается в "ng-click":

scope.updateSelect = function (type) {
    scope.selectionCtrl.activeList = scope.seedLists[type]; 
    scope.selectionCtrl.activeListKey = type; 
    scope.selectionCtrl.activeSelection = scope.selection[type];
    scope.selectionCtrl.staged = [];
    scope.selectionCtrl.stageRemove = [];
    if (type !== scope.activeTab) {
        scope.activeTab = type;
    }
    console.log("update");
};

scope.$watch('selectionCtrl.activeList', function(newValue, oldValue) {
    console.log("watch");
}, true);

Когда я нажимаю кнопку (запускает updateSelect) и смотрю консоль, я вижу "обновление", а затем "смотреть". Первое, что происходит внутри функции, - это selectionCtrl.activeList, поэтому я ожидаю увидеть "смотреть", а затем "обновить".

Не следует смотреть триггер сразу после изменения массива?

Ответ 1

Функция должна заканчиваться первой, поскольку javascript является одиночным.

Поскольку функция вызывается с помощью директивы ng-click, angular будет запускать цикл дайджеста. Часть этого цикла дайджеста состоит в том, чтобы запускать список часов и разрешать все изменения, которые могли произойти с момента последнего запуска цикла.

В примере, который вы даете, selectionCtrl.activeList изменяется в updateSelect, который впоследствии приводит к вызову обратного вызова.

Ответ 2

Когда Angular выполняет watch обратный вызов?

Это связано с $digest и $apply, и, конечно же, оно не выполняется в вашем исходном коде JavaScript.

Чтобы принудительно выполнить watch, вы можете запустить $scope.apply() вручную, но может вызвать дополнительную проблему и не нужно, если она находится в пределах функции angularjs, то есть $timeout, $interval и т.д., потому что она будет вызвана автоматически после функции.

Для получения дополнительной информации, поиска,

Ответ 3

https://docs.angularjs.org/api/ng/type/ $rootScope.Scope:

Вызов watchExpression вызывается при каждом вызове $digest() и должен возвращать значение, которое будет наблюдаться. (Так как $digest() повторно запускает, когда обнаруживает изменения, watchExpression может выполняться несколько раз за $digest() и должен быть идемпотентным.)

Если вы попробуете i.e.:

scope.selectionCtrl.activeList = scope.seedLists[type]; 
scope.$digest();

вы получите сообщение об ошибке: [$ rootScope: inprog] $применяется уже в процессе.