首页 > 解决方案 > ExpressionChangedAfterItHasBeenCheckedError 与共享服务

问题描述

我们有一个加载了子组件的根布局组件。布局组件绑定到共享布局服务中的属性。子组件在共享布局服务中设置属性。每当我们从子组件更改属性时,我们会在非 prod 模式下收到以下错误: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked

这真的很烦人。如果不执行 cdr.detectChanges(),就没有其他方法可以使这个工作吗?

这是一个应该可以工作的简单场景……</p>

app.component.html
------------------
<layout>

</layout>

layout.component.html
---------------------
<div *ngFor="let menuItem of layoutService.menuItems">
  {{menuItem.content}}
</div>

layout.component.ts
-------------------
@Injectable()
export class LayoutComponent{
   constructor(public layoutService: LayoutService){}
   ...
}   

layout.service.ts
-----------------
export class LayoutService {
  menuItems: MenuItem[];
  ...
}

child-component-in-router-outlet.component.ts
---------------------------------------------
export class ChildComponentInRouterOutletComponent {

    constructor(private layoutService: LayoutService){}

    ngOnInit(): void{
        this.layoutService.menuItems = [ ... ];
    }
}

如果在此示例中我将 de menuItems 属性转换为 BehaviorSubject 它也不起作用。

标签: angular

解决方案


我通过在 NavigationEnd 上执行 detectChanges 来修复它,如下所示:

this.router.events.subscribe(event => {
    if (event instanceof NavigationEnd) {
        this.cdr.detectChanges();
    }
});

有了这个,你只在组件被加载到路由器出口并且在共享服务上设置了属性之后才调用一次detectChanges。


推荐阅读