Ответ 1
$$phase
- это флаг, а angular - в цикле $digest
.
Иногда (в редких случаях) вы хотите проверить $$phase
на области, прежде чем делать $apply
. Ошибка при попытке $apply
во время $digest
:
Ошибка: $apply уже выполняется
Я нашел этот фрагмент кода, который является частью директивы angular, которую кто-то написал для bootstrap modal.
//Update the visible value when the dialog is closed
//through UI actions (Ok, cancel, etc.)
element.bind("hide.bs.modal", function () {
scope.modalVisible = false;
if (!scope.$$phase && !scope.$root.$$phase)
scope.$apply();
});
Я понял, что эта часть предназначена для последней половины двусторонней привязки, которую мы связываем с hide.bs.modal событием и модификацией модальности при изменении пользовательского интерфейса.
Я просто хотел знать, почему пользователь проверяет $$ фазу для области и rootScope до вызова?
Не можем ли мы сразу позвонить?
Что такое $$ phase здесь?
Я много искал, не мог найти никакого хорошего объяснения.
EDIT:
Я нашел, где я увидел пример: Простая angular Директива для Модификации Bootstrap
$$phase
- это флаг, а angular - в цикле $digest
.
Иногда (в редких случаях) вы хотите проверить $$phase
на области, прежде чем делать $apply
. Ошибка при попытке $apply
во время $digest
:
Ошибка: $apply уже выполняется
Давин абсолютно прав, что он устанавливает флаг angular во время цикла дайджест.
Но не используйте его в своем коде.
Недавно я получил шанс спросить Misko (angular автора) о $$ phase, и он сказал, что никогда не использовал его; это внутренняя реализация цикла дайджеста, и это не безопасно в будущем.
Чтобы ваш код продолжал работать в будущем, он предложил обернуть все, что вы хотите "безопасно применить" внутри $timeout
$timeout(function() {
// anything you want can go here and will safely be run on the next digest.
})
Это очень много, если у вас есть обратные вызовы или другие вещи, которые могут быть разрешены во время цикла дайджеста (но не всегда)
Вот фрагмент примера, когда я имел дело с одной из библиотек google: (Остальная часть службы, из которой это было, была остановлена.)
window.gapi.client.load('oauth2', 'v2', function() {
var request = window.gapi.client.oauth2.userinfo.get();
request.execute(function(response) {
// This happens outside of angular land, so wrap it in a timeout
// with an implied apply and blammo, we're in action.
$timeout(function() {
if(typeof(response['error']) !== 'undefined'){
// If the google api sent us an error, reject the promise.
deferred.reject(response);
}else{
// Resolve the promise with the whole response if ok.
deferred.resolve(response);
}
});
});
});
Обратите внимание, что аргумент задержки для $timeout не является обязательным и по умолчанию будет 0, если оставить его неактивным ($timeout вызывает $browser.defer, который по умолчанию равен 0, если задержка не установлена )
Немного неинтуитивно, но ответ от ребята, пишущего Angular, поэтому он достаточно хорош для меня!
В этом примере привязка элемента будет выполнена из события не angular. В большинстве случаев безопасно просто вызвать $apply()
без проверки фазы.
Если вы посмотрите на остальную часть кода, есть функция $scope
, называемая showModal()
. Эта функция вызывает код не angular, который, вероятно, вызовет событие "hide.bs.modal". Если событие срабатывает по этому маршруту, стек вызовов находится в пределах $digest
.
Таким образом, это событие попадает в редкий случай функции, которая будет вызвана как из кода angular -установленного кода, так и не-w500 > . Проверка $$phase
в этом случае необходима, потому что вы не знаете, как произошло событие. Если для параметра $$phase
установлено что-то, тогда цикл digest завершится до завершения и $apply()
не нужно вызывать.
Этот шаблон часто упоминается как "safe apply" .
Мое понимание - это хорошо использовать при переваривании или применении области. Если это правда, это означает, что в настоящее время выполняется этап $digest или $apply. Если вы получаете связанные ошибки, вы можете сделать $scope. $$ phase || $Scope.digest(); который будет только переваривать, если $scope. $$ pahse является ложным.