Когда использовать Ngzone.run()?
Я получил ошибку в моем угловом проекте, которая в конце концов была решена путем переноса кода в
this.zone.run(() => {/* my code here */});
как указано в этом ответе.
Мое предыдущее понимание zone
было то, что угловой не может обнаружить изменения, сделанные асинхронным callbacks
сторонних библиотек, потому что "они не в угловых zone
". Если я нажму на button
событие, которое запускается, не является родным для браузера click
событие но обычай (пропатченный) click
событие, созданное угловым, чей handler
работает в zone
поэтому angular знает об изменениях, сделанных его обработчиком обратного вызова.
Но я не мог понять, запустив router.navigate()
в обратном вызове третьей стороны создайте эту проблему (как указано в этой проблеме github). не Router
service
угловой сам по себе? Почему он не сообщает автоматически Angular's zone
когда вызывается в третьей стороне callback
?
Я получил эту проблему с помощью router.navigate
в состоянии редуктора NGXS.
Мой вопрос:
Может кто-нибудь объяснить, когда именно мне нужно обернуть мой код в NgZone
?
Отладка в течение нескольких часов и понимание того, что мой код не работает zone
контекст утомителен.
1 ответ
Ng Zone.runOutsideAngular() - запускает код за пределами угловой зоны.
- Когда запускается какое-то событие, он сообщает angular об обнаружении изменений.
- Если вы используете событие mouseUp() или mouseDown(), то при каждом изменении оно сообщает angular об обнаружении изменений.
- Если мы не хотим, чтобы эти изменения выполнялись во время выполнения в angular (что снижает производительность приложения), мы можем запустить его за пределами угловой зоны.
- В отличие от этого, если мы очень хотим получать каждое обновление, мы можем использовать ngZone.run(). Означает, что обнаружение изменений будет выполняться в обычном режиме.
Сам Angular использует ngZone под капотом для обнаружения изменений
Итак, если мы вышли из угловой зоны, то для возврата используем ngZone.run()
Zone.js - это контекст выполнения для отслеживания и перехвата асинхронных операций, таких как: События DOM (
click
,keydown
,keyup
,etc
),setTimeout
,setInterval
.XMLHttpRequest
s)
NgZone - это просто угловая служба-оболочка вокруг Zone.js
API.
Команда Angular решила, что им нужна абстракция для контекста выполнения при работе над Angular, поэтому они создали Zone.js и оболочку (неформально - шаблон адаптера) вокруг него в Angular.
Итак, в основном, чтобы ответить на ваш вопрос: при работе с любой сторонней библиотекой, которая не привязана к контексту запуска Angular в Zone.js (если вы не решили, что вам не нужен контекст выполнения, и вы можете работать без него, используяNoopNgZone
)
ngZone.run()
особенно полезен при модульном тестировании вашей маршрутизации.
it('should redirect if condition true, fakeAsync(() => {
router.navigate(['']);
fixture.ngZone.run(() => {
component.redirectIfConditionTrue();
});
tick();
expect(location.path()).toBe('/AgentLeadsManager');
}));
- источник: это единственный раз, когда мне приходилось его использовать
Используете ли вы BrowserAnimationsModule?
У меня была та же проблема с необходимостью обернуть некоторые перенаправления маршрутизатора в zone.run(), и это может быть из-за этой открытой ошибки: