具有共享服务的ExpressionChangedAfterItHasBeenCheckedError

时间:2018-11-09 10:07:48

标签: angular

我们有一个加载了子组件的根布局组件。 De布局组件绑定到共享布局服务中的属性。子组件在共享布局服务中设置属性。每当我们从子组件更改属性时,在非生产模式下都会出现以下错误: ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改

这真令人讨厌。没有其他没有cdr.detectChanges()做这个工作的人吗?

这是一个应该起作用的简单方案……

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,则它也无效。

1 个答案:

答案 0 :(得分:0)

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

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

使用此方法,仅在将组件加载到路由器出口中并在共享服务上设置属性之后,才调用一次detectChanges。