programing

Angular zone 외부에서 트리거된 탐색입니다. 'ngZone.run()'을 호출하는 것을 잊으셨습니까?

newstyles 2023. 5. 4. 19:42

Angular zone 외부에서 트리거된 탐색입니다. 'ngZone.run()'을 호출하는 것을 잊으셨습니까?

Angular 7을 사용하고 있으며 로그인 후 API GET 호출이 성공하고 구성 요소가 데이터를 수신하는 문제가 발생했지만 UI에서 해당 데이터가 표시되지 않습니다.

브라우저 콘솔을 열면 즉시 UI에 데이터가 채워지고 콘솔에 경고가 표시됩니다.

"core.js:15686 Angular zone 외부에서 트리거된 탐색입니다. 'ngZone.run()'을 호출하는 것을 잊으셨습니까?

는 이 하여 이 경 검 다 같 찾 해 방 을 았 습 법 니 다 결 은 고 과 를 음 여 색 하 ▁like 니 around 다 습 찾 ▁and ▁work ▁i 았 ▁some 을 ▁found 이▁go led ogthis.ngZone.run()API를 호출합니다.

하지만 문제는 제가 40개 이상의 구성 요소를 사용하고 있고 각 구성 요소에서 수많은 API를 호출하고 있다는 것입니다.그래서 전화를 해야 합니다.ngZone.run()으로 보이는 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

이 문제를 극복하기 위한 더 나은 접근법은 무엇입니까?

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');
    }

일반적으로 각도 코드와 관련이 없는 외부 JavaScript에서 일부 외부 js 콜백 내에서 각도 호출을 래핑할 때 발생합니다.

»app.component.ts:

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

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

NgZone에 . 를 들어, "" "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;
    });
}

라우터 탐색 명령어를 ngZone으로 감아서 제 문제가 해결되었습니다.아래 코드를 확인하십시오.

생성자에서 "개인 영역:NgZone".

private zone: NgZone

this.zone.run(() => {
                    this.router.navigate(['/login']);
                });

위에서 얘기하면 이 경고의 의미는 이벤트가 영역 밖에서 트리거된다는 것입니다.Angular는 변경 감지UI 렌더링을 위한 실행 컨텍스트라고도 하는 영역을 사용합니다.따라서 탐색하는 동안 Angular는 UI를 다시 렌더링하기를 기대하지만 여기서는 그렇지 않습니다.그것이 당신이 직면한 문제입니다.따라서 실행된 코드가 Angular zone 내부에 있을 때 Angular가 변경 감지 및 UI 렌더링을 처리하고 있기 때문에 이 경고가 발생합니다.

그러나 실제로 가입 방법 에서 라우터 탐색을 호출하려고 할 때 이 경고가 발생합니다.

라우터 탐색 통화를 외부에 둔 경우subscribe메소드를 선택하면 이 경고를 다시 던지지 않고 탐색 후 예상되는 UI를 볼 수 있습니다.

영역에 대한 자세한 내용은 아래에 언급된 비디오를 읽고 시청하십시오.

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

저도 같은 문제가 있었습니다.제게 효과가 있었습니다. 두 가지 방법이 있습니다.

첫 번째 양식:

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");

당신에게 효과가 있기를 바랍니다.

제 경우, 테스트된 구성 요소가 경로 변경에 올바르게 반응하는지 확인하기 위해 라우터를 호출하는 테스트로 인해 문제가 발생했습니다.제 테스트의 코드는 대략 다음과 같습니다.

const router: Router = TestBed.inject(Router);
await router.navigateByUrl('some-route');

NgZone을 주입하고 라우터 호출을 포장하는 것이 해결책이었습니다.

const router: Router = TestBed.inject(Router);
const ngZone: NgZone = TestBed.inject(NgZone);
await ngZone.run(async () => router.navigateByUrl('some-route'));

이는 탐색을 트리거하는 구성 요소 방법을 직접 테스트하는 경우에도 필요합니다.

const ngZone: NgZone = ngZone = TestBed.inject(NgZone);
ngZone.run(() => component.someMethod()); // someMethod() triggers a router navigation

작업 솔루션 - 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);
      });
    });
  }

사용자 지정 서비스를 주입하려고 하면 다음과 같은 문제가 발생합니다.

constructor(private myService: MyService) {
}

모듈 구성에 제공하는 것을 잊어버린 경우:

@NgModule({
  providers: [
    MyService
  ]

언급URL : https://stackoverflow.com/questions/53645534/navigation-triggered-outside-angular-zone-did-you-forget-to-call-ngzone-run