Одна важная вещь, которую следует иметь в виду при работе с инструментами сторонних разработчиков, а также внешними событиями DOM в AngularJS, заключается в использовании операции метода $scope.$apply()
для запуска изменений. Это работает потрясающе, но иногда сама область, которую я уже измельчаю через дайджест (в основном это триггеры $apply), и при вызове $apply, когда это происходит, выдает ошибку. Поэтому, чтобы обойти это, вам нужно будет обратить внимание на флаг $scope.$$phase
, который устанавливается в область всякий раз, когда происходит дайджест.
Итак, скажем, вы хотите изменить URL-адрес, и вы запустите его:
$scope.$apply(function() {
$location.path('/home');
});
И это работает так, как ожидалось, но теперь давайте предположим, что $scope занят этим. Поэтому вместо этого вы проверяете переменную фазы $$ и предполагаете, что ваши изменения будут подняты:
if($scope.$$phase) {
$location.path('/home');
}
else {
$scope.$apply(function() {
$location.path('/home');
});
}
Это то, что я делал (очевидно, не с дублированием кода), и, похоже, он работает в 100% случаев. Что меня беспокоит, так это то, что как AngularJS набирает изменения, когда область действия находится на полпути к ее перевариванию?
Возможно, этот пример недостаточно конкретный. Предположим вместо этого что-то большее. Представьте себе, если у вас есть огромная веб-страница с множеством привязок и позволяет предположить, что переваривание будет переваривать страницу линейно (я предполагаю, что он делает что-то подобное в отношении приоритета... В этом случае будет то, что появляется в DOM tree) и обновить привязки на странице сверху вниз.
<div class="binding">{{ binding1 }}</div>
<div class="binding">{{ binding2 }}</div>
<div class="binding">{{ binding3 }}</div>
<div class="binding">{{ binding4 }}</div>
<div class="binding">{{ binding5 }}</div>
<div class="binding">{{ binding6 }}</div>
<div class="binding">{{ binding7 }}</div>
<div class="binding">{{ binding8 }}</div>
Предположим, что происходит переваривание, и оно находится где-то около середины очереди пищеварения. Теперь попробуйте изменить значение привязки в верхней части страницы.
if($scope.$$phase) {
$scope.binding1 = 'henry';
}
Теперь, каким-то образом, AngularJS подбирает изменения и правильно обновляет привязку. Даже если само изменение можно считать более ранним в очереди по отношению к HTML/DOM.
Мой вопрос: как AngularJS управляет этим потенциальным состоянием гонки? Мне может быть комфортно, если обновление binding8 (так как оно ниже страницы), но поскольку binding1 также обновляется (сразу же без необходимости повторного вызова $apply), это делает меня немного потерянным. Означает ли это, что другое переваривание было отправлено где-то посередине? Или объект $scope более волшебный, чем я ожидаю? Я бы предположил, что эта проблема была до сих пор, но так как выяснение порядка $$ phase и $scope в первую очередь было немного сложным, я предполагаю, что это тоже может быть чем-то, что попало в трещины.
Любые идеи?