我正在尝试处理具有多个组件的项目。示例应用是here。我处于这样一种情况,我在开发模式中得到如下错误
我知道为什么会出现这个错误
因为在子组件值绑定后,父组件 值由祖父组件更新,导致抛出 角度脏检查时出错
我的应用的骨架是here。有人可以帮我解决这个问题。我知道它可以通过使用setTimeout或changeDetectionRef来解决。但那不是我想要的解决方案,我想知道在生命周期钩子中我做错了什么。提前谢谢。
答案 0 :(得分:2)
很高兴听到您反对setTimeout
并手动拨打detectChanges
。
我知道这在您的应用结构中很明显,但这里有一个示例,可以显示错误的来源:
因为在子组件值绑定后,父组件 值由祖父组件更新,导致抛出 角度脏检查时出错
似乎你在ngAfterContentInit发生之前渲染了你的子组件。
Angular应用程序是一个视图树。当角度运行改变检测机制时,它会通过这个视图,并为每个视图调用checkAndUpdateView函数。
在执行此函数期间,angular以严格定义的顺序调用其他函数。在我们的案例中,我们对这些功能感兴趣:
execEmbeddedViewsAction
callLifecycleHooksChildrenFirst (AfterContentInit)
execComponentViewsAction
这意味着 angular将比执行ng-template
hook 更早地调用嵌入视图的更改检测周期(ngAfterContentInit
生成嵌入视图)。这就是你的例子中发生的事情:
正如我们在上图中看到的,当角度检查AppComponent视图时,它首先检查嵌入的视图,然后调用ngAfterContentInit
GrandParentComponent
并向下查看GrandParentComponent
。
似乎有很多方法可以解决它。我在 Demo
中试用了它们关键时刻不使用ngAfterContentInit
挂钩,而是在ParentComponent
中设置索引和有效值:
<强> parent.component.ts 强>
export class ParentComponent {
private _active: boolean = false;
public index = 0;
constructor(
@Host() @Inject(forwardRef(() => GrandParentComponent))
public grandParentComponent: GrandParentComponent) {
this.index = this.grandParentComponent.parents.length;
this.grandParentComponent.parents.push(this)
}
ngOnInit() {
this.active = this.index == this.grandParentComponent.currentStep;
}
ngOnDestroy() {
if (this.grandParentComponent) {
this.grandParentComponent.parents = this.grandParentComponent.parents.filter(x => x !== this);
}
}
其中parent属性已在GrandParentComponent
中声明:
<强> grandparent.component.ts 强>
export class GrandParentComponent {
parents = [];