Когда использовать 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. XMLHttpRequests)

NgZone - это просто угловая служба-оболочка вокруг Zone.jsAPI.

Команда 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(), и это может быть из-за этой открытой ошибки:

https://github.com/angular/angular/issues/20290

Другие вопросы по тегам