Navigasi dipicu di luar zona Angular, apakah Anda lupa memanggil 'ngZone.run()'?

Saya menggunakan Angular 7 dan menghadapi masalah => setelah login, panggilan API GET berhasil dan komponen juga menerima data, tetapi UI tidak menampilkan data itu.

Saat saya membuka konsol browser, data segera diisi di UI dan peringatan muncul di konsol.

"core.js:15686 Navigasi dipicu di luar zona Angular, apakah Anda lupa memanggil 'ngZone.run()'?"

Saya telah mencari peringatan ini di Google dan menemukan beberapa solusi seperti this.ngZone.run() dan memanggil API saya di dalamnya.

Namun masalahnya, saya menggunakan lebih dari 40 komponen dan memanggil begitu banyak API di setiap komponen. Jadi saya harus memanggil ngZone.run() pada setiap panggilan API, yang sepertinya sulit dilakukan.

Tolong sarankan saya pendekatan yang lebih baik untuk mengatasi masalah ini. Terima kasih sebelumnya.

aplikasi.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 sumber
comment
Silakan bagikan kode komponen/layanan terkait Anda.   -  person Ravinder Payal    schedule 06.12.2018
comment
@ Ravinder Payal: Komponen/layanan bersama   -  person Er Vipin Sharma    schedule 06.12.2018
comment
Itu tidak menyelesaikan tujuannya. silakan bagikan kode bootstrap untuk getEmployees. Dari mana Anda menelepon getEmployees(): void   -  person Ravinder Payal    schedule 06.12.2018
comment
Memanggilnya dari metode ngOnInit() di komponen.   -  person Er Vipin Sharma    schedule 06.12.2018
comment
Saya juga menerima pesan kesalahan ini. Saya akan membuka postingan lain untuk melihat apakah kasus saya lebih jelas.   -  person AlanObject    schedule 03.01.2019
comment
cuplikan tidak menunjukkan penggunaan perutean, yang merupakan bagian yang menyebabkan pesan yang diberikan. Panggilan http saja tidak akan menyebabkannya. Adakah hal menarik yang terjadi dengan employees jika disetel di app.component.ts?   -  person André Werlang    schedule 21.02.2019
comment
bagaimana getEmployees() dipanggil? Apakah itu dipanggil langsung dengan beberapa klik, atau digabungkan dengan beberapa panggilan balik?   -  person albanx    schedule 10.03.2019
comment
jika Anda mendapatkan ini saat pengujian unit, periksa - github.com/angular/angular/issues/25837   -  person danday74    schedule 24.03.2021


Jawaban (6)


Biasanya ini terjadi ketika Anda membungkus panggilan sudut di dalam beberapa panggilan balik js eksternal, dari JavaScript eksternal yang tidak terkait dengan kode sudut.

Contoh 1_:

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

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

Dalam hal ini Anda harus memasukkan panggilan ke NgZone, contoh: this.ngZone.run(() => this.getEmployees());

app.component.ts kemudian akan terlihat seperti berikut:

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
Dalam kasus saya ini terjadi di langganan rxjs yang dibuat oleh komponen sudut. - person m1ld; 03.10.2019
comment
Terima kasih banyak, saya menggunakan panggilan balik integrasi Razorpay, tidak ada yang berhasil. - person Warewolf; 13.04.2020
comment
terima kasih @albanx, saya juga menghadapi masalah ini, jawaban Anda telah menyelesaikan masalah saya - person kushal shah; 13.05.2020
comment
@Er Vipin Sharma Saya harap Anda dapat menerima jawaban yang luar biasa ini. - person Sampath; 13.06.2020

Masalah saya diperbaiki dengan menggabungkan perintah navigasi router di ngZone. Silakan periksa kode di bawah ini

di konstruktor tambahkan zona pribadi: NgZone.

private zone: NgZone

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

Kalau saya bicara dari atas maka maksud dari peringatan ini adalah event tersebut dipicu di luar zona. Angular menggunakan zona, juga disebut konteks eksekusi untuk deteksi perubahan dan rendering UI. Jadi saat menavigasi, Angular berharap untuk merender ulang UI tetapi hal itu tidak terjadi di sini. Itulah masalah yang Anda hadapi. Jadi peringatan ini muncul karena Angular sedang memproses deteksi perubahan dan rendering UI ketika kode yang dieksekusi terletak di dalam zona Angular.

Namun sebenarnya, peringatan ini muncul ketika Anda mencoba memanggil navigasi router di dalam metode berlangganan.

Jika Anda melakukan panggilan navigasi router di luar metode subscribe maka peringatan ini tidak akan muncul lagi dan Anda akan melihat UI yang diharapkan setelah navigasi.

Untuk informasi lebih lanjut tentang zona, baca dan tonton video di bawah ini:

https://blog.thinktram.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
Saya memiliki panggilan router.navigate() di dalam blok metode subscribe(). Ketika Anda mengatakan untuk meletakkannya di luar, di manakah tepatnya itu berada? - person Stephane; 04.08.2019
comment
Bagi saya, pemutakhiran ke Angular 8 membuat panggilan router yang ada di dalam penangan kesalahan memicu kesalahan 'Navigasi dipicu di luar zona Angular'. Saya harus menghapus panggilan router.navigate() di blok penangan kesalahan khusus errorService.log(error).subscribe(errorWithContextInfo => { - person Stephane; 04.08.2019

Saya memiliki masalah yang sama. Ini berhasil untuk saya, Anda memiliki dua cara:

Bentuk pertama:

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

Masalahnya adalah ini akan memuat ulang seluruh aplikasi dan membuatnya lebih lambat

Metode kedua:

Impor ini

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

konstruktor:

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


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

Jadi ketika Anda ingin membuka komponen Anda, cukup:

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

Saya harap ini berhasil untuk Anda

person Jhoan    schedule 02.03.2021

Solusi Kerja - PERBAIKI

 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

Ini terjadi jika Anda mencoba memasukkan layanan yang dibuat khusus:

constructor(private myService: MyService) {
}

sementara Anda lupa menyediakannya dalam konfigurasi modul:

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