Навигация сработала за пределами зоны Angular, вы забыли вызвать ngZone.run ()?

Я использую Angular 7 и сталкиваюсь с проблемой => после входа в систему API GET вызывает успешно и компонент также получает данные, но пользовательский интерфейс не отображает эти данные.

Когда я открываю консоль браузера, данные сразу же заполняются пользовательским интерфейсом, а в консоли отображается предупреждение.

"core.js: 15686 Навигация запущена вне зоны Angular, вы забыли вызвать 'ngZone.run ()'?"

Я погуглил это предупреждение и нашел обходной путь, например this.ngZone.run(), и вызвал свой API внутри него.

Но проблема в том, что я использую более 40 компонентов и вызываю так много API в каждом компоненте. Поэтому мне приходится вызывать ngZone.run() при каждом вызове API, что, кажется, сложно сделать.

Пожалуйста, предложите мне лучший подход для решения этой проблемы. Заранее спасибо.

app.component.ts

getEmployees(): void {
    this.employeeService.getEmployees().subscribe(e => {
        this.employees = e;
    });
}

app.service.ts

@Injectable()
export class EmployeeService {
    constructor(private httpClient: HttpClient) { }

    getEmployees() {
        return this.httpClient.get<EmployeeModel[]>('employees');
    }

person Er Vipin Sharma    schedule 06.12.2018    source источник
comment
Поделитесь, пожалуйста, кодом вашего компонента / сервиса.   -  person Ravinder Payal    schedule 06.12.2018
comment
@ Ravinder Payal: общий компонент / сервис   -  person Er Vipin Sharma    schedule 06.12.2018
comment
Это не решение цели. пожалуйста, поделитесь кодом начальной загрузки для getEmployees. Откуда вы звоните getEmployees(): void   -  person Ravinder Payal    schedule 06.12.2018
comment
Вызов его из метода ngOnInit () в компоненте.   -  person Er Vipin Sharma    schedule 06.12.2018
comment
Я тоже получаю это сообщение об ошибке. Я открою еще одну публикацию, чтобы узнать, понятнее ли мое дело.   -  person AlanObject    schedule 03.01.2019
comment
фрагменты не показывают использование маршрутизации, которая является частью, которая могла бы вызвать предоставленное сообщение. Сам по себе http-вызов этого не вызовет. Что-нибудь интересное происходит с employees при установке app.component.ts?   -  person André Werlang    schedule 21.02.2019
comment
как вызывается getEmployees()? Вызывается ли он напрямую каким-то щелчком мыши или он заключен в некоторые обратные вызовы?   -  person albanx    schedule 10.03.2019
comment
если вы получите это при модульном тестировании, проверьте - github.com/angular/angular/issues/25837 < / а>   -  person danday74    schedule 24.03.2021


Ответы (6)


Обычно это происходит, когда вы обертываете угловые вызовы внутри некоторого внешнего обратного вызова js из внешнего JavaScript, не связанного с угловым кодом.

Пример app.component.ts:

callMyCustomJsLibrary() {
  googleSdk.getLocations(location => this.getEmployees());
}

getEmployees(): void {
    this.employeeService.getEmployees().subscribe(e => {
        this.employees = e;
    });
}

В этом случае вам нужно будет включить вызов в NgZone, например: this.ngZone.run(() => this.getEmployees());

Тогда app.component.ts будет выглядеть следующим образом:

callMyCustomJsLibrary() {
  googleSdk.getLocations(location => this.ngZone.run(() => this.getEmployees()));
}

getEmployees(): void {
    this.employeeService.getEmployees().subscribe(e => {
        this.employees = e;
    });
}
person albanx    schedule 10.03.2019
comment
В моем случае это происходит в подписке rxjs, созданной угловым компонентом. - person m1ld; 03.10.2019
comment
Спасибо большое, зависал с обратным вызовом интеграции razorpay, ничего не работало. - person Warewolf; 13.04.2020
comment
спасибо @albanx, я тоже столкнулся с этой проблемой, ваш ответ решил мою проблему - person kushal shah; 13.05.2020
comment
@Er Vipin Sharma Надеюсь, вы примете этот потрясающий ответ. - person Sampath; 13.06.2020

Моя проблема решена путем переноса команды навигации маршрутизатора в ngZone. Пожалуйста, проверьте код ниже

в конструкторе добавить приватную зону: NgZone.

private zone: NgZone

this.zone.run(() => {
                    this.router.navigate(['/login']);
                });
person Shakoor Hussain Attari    schedule 07.10.2020

Если я говорю сверху, то это предупреждение означает, что событие запускается за пределами зоны. Angular использует зоны, также называемые контекстами выполнения для обнаружения изменений и визуализации пользовательского интерфейса. Итак, при навигации Angular ожидает повторного рендеринга пользовательского интерфейса, но здесь этого не происходит. Это проблема, с которой вы столкнулись. Таким образом, он выдает это предупреждение, потому что Angular обрабатывает обнаружение изменений и рендеринг пользовательского интерфейса, когда выполняемый код находится внутри зоны Angular.

Но на самом деле это предупреждение появляется, когда вы пытаетесь вызвать навигацию по маршрутизатору внутри метода подписки.

Если вы поместите вызов навигации маршрутизатора вне метода subscribe, он больше не будет выдавать это предупреждение, и вы увидите ожидаемый пользовательский интерфейс после навигации.

Для получения дополнительной информации о зонах прочтите и посмотрите видео, указанные ниже:

https://blog.othingtram.io/angular/2017/02/21/using-zones-in-angular-for-better-performance.html#running-outside-angulars-zone

https://www.youtube.com/watch?v=3IqtmUscE_U&t=150

person Sunny Goel    schedule 21.03.2019
comment
У меня есть вызов router.navigate() внутри блока subscribe() метода. Когда вы говорите поставить его на улицу, где именно это будет? - person Stephane; 04.08.2019
comment
Для меня обновление до Angular 8 привело к тому, что существующий вызов маршрутизатора внутри обработчика ошибок вызвал ошибку «Навигация, запущенная вне зоны Angular». Мне пришлось удалить вызов router.navigate() в блоке пользовательского обработчика ошибок errorService.log(error).subscribe(errorWithContextInfo => { - person Stephane; 04.08.2019

У меня такая же проблема. У меня это сработало, у вас есть два пути:

Первая форма:

document.location.href=`/component/${param}/...`

Проблема в том, что он перезагрузит все приложение, и это замедлит его работу.

Второй способ:

Импортировать это

import { Router } from '@angular/router';
import { Component, NgZone } from '@angular/core';

конструктор:

 constructor(private _ngZone: NgZone, private _router: Router) { }


  goTo(comp, param){
    this._ngZone.run(()=>{
    this._router.navigate([comp, param])
    });
  }

Поэтому, когда вы хотите перейти к своему компоненту, просто:

this.goTo("/myComponent", "my-param-value");

Я надеюсь это сработает для тебя

person Jhoan    schedule 02.03.2021

Рабочее решение - FIX

 ngAfterViewInit(): void {
    let self = this;
      this.platform.backButton.subscribe(() => {
      console.log("back preseed \n \n");

      self._ngZone.runOutsideAngular(() => {
        setTimeout(() => {
          self.Router.navigateByUrl("/stock-management");
        }, 100);
      });
    });
  }
person Shashwat Gupta    schedule 16.07.2021

Это произойдет, если вы попытаетесь внедрить заказную услугу:

constructor(private myService: MyService) {
}

пока вы забыли указать это в конфигурации модуля:

@NgModule({
  providers: [
    MyService
  ]
person Stephane    schedule 17.04.2019