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] $применяется уже в процессе.