Навигация, вызванная вне угловой зоны, вы забыли назвать "ngZone.run()"?

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

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

"core.js: 15686 Навигация, вызванная вне угловой зоны, вы забыли позвонить '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');
    }

Ответ 1

Обычно это происходит, когда вы оборачиваете угловые вызовы внутри некоторого внешнего 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;
    });
}

Ответ 2

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

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

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

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

https://blog.thoughtram.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

Ответ 3

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

constructor(private myService: MyService) {
}

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

@NgModule({
  providers: [
    MyService
  ]