我读过有关 NG0100: ExpressionChangedAfterItHasBeenCheckedError in Angular 的内容,但在我的情况下我无法避免它。
基本上,在拦截器上,我有一个加载“状态”真/假的服务:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
this.showLoader();
return next.handle(req).pipe(
catchError((error) => {
return error;
}),
finalize(() => {
this.hideLoader();
})
);
}
Run Code Online (Sandbox Code Playgroud)
在应用程序组件内使用ngAfterViewInit会引入该错误:
ngOnInit(): void {}
ngAfterViewInit() {
this.getData().subscribe((data) => {
this.childSelector.loadRecipeRoadmap(data.name);
});
}
Run Code Online (Sandbox Code Playgroud)
我需要使用它:事实上,当加载所有子项时,父项必须“发送”(一次)数据给子项(仅在开始时)。在某些时候,我只需要从孩子那里读取(这就是我使用 ViewChild 而不是 @Output 机制的原因)。
我该如何修复这个特定错误?我应该同步 Observable 吗?不知道如何...
car*_*cki 38
这是因为您正在执行 中的一些代码ngAfterViewInit,这会修改显示的数据。
第一个检测周期评估ngIf为false,然后ngAfterViewInit执行,然后执行第二个验证检测周期(角度展开模式有这个附加的),这次ngIf评估为true。因此出现了臭名昭著的错误。
对此有几种解决方案:
由于您的数据获取无论如何都是异步的,因此您可以在 0 时间延迟ngAfterViewInit的帮助下推迟它在下一个宏任务(完成后)中调用:setTimeout
ngAfterViewInit() {
setTimeout(() => {
this.getData().subscribe((data) => {
this.childSelector.loadRecipeRoadmap(data.name);
});
});
}
Run Code Online (Sandbox Code Playgroud)
您可以在修改显示的数据后通知 Angular 运行额外的检测周期。
constructor(private http: HttpClient, public loader: LoaderService, private changeDetectorRef: ChangeDetectorRef) {}
ngAfterViewInit() {
this.getData().subscribe((data) => {
this.childSelector.loadRecipeRoadmap(data.name);
});
this.changeDetectorRef.detectChanges();
}
Run Code Online (Sandbox Code Playgroud)
或者也许更有角度的方式:
不要等待子组件创建并直接与其交互,而是执行数据加载OnInit并将数据绑定到子组件:
export class AppComponent {
dataForChild: any;
constructor(private http: HttpClient, public loader: LoaderService) {}
ngOnInit(): void {
this.getData().subscribe((data) => this.dataForChild = data.name);
}
Run Code Online (Sandbox Code Playgroud)
并将其绑定(当然myData在子组件中需要成为并输入属性@Input())
<app-my-child [myData]="dataForChild"></app-my-child>
Run Code Online (Sandbox Code Playgroud)
您正在订阅 observable,但不要取消订阅(既不使用unsubribe()也不使用takeUntil())。虽然从 Angular http 模块订阅 observables 不会导致内存泄漏,但最好确保您无论如何都会取消订阅,原因如下:
ngOnDestroy,待处理的 http 请求将被取消,从而释放已用请求的浏览器池pipe的转换中也不会被调用,因此由于不执行不必要的代码而具有更好的性能| 归档时间: |
|
| 查看次数: |
35798 次 |
| 最近记录: |