Angular中的ngAfterViewInit在每次changeDetection后都会被调用

6

ngAfterViewInit()是Angular文档中的一个钩子。

ngAfterViewInit()

在Angular初始化组件的视图和子视图后进行响应。

在第一次调用ngAfterContentChecked()之后仅调用一次

这是一个仅适用于组件的钩子。

我有一个嵌套在组件T中的组件C

组件C实现了以下钩子。

ngAfterViewInit(): void {
        console.log("afterViewInit");
        debugger;
    }

当用户点击单元格时,会触发表格组件T的变更检测。

表格单元格中可以找到组件C

每当我点击单元格,就可以在控制台中看到afterViewInit日志。

我的堆栈跟踪如下:

DynamicComponentWrapper.ngAfterViewInit (dynamic-component-wrapper.ts:72) View_TableComponent18.detectChangesInternal (/TableModule/TableComponent/component.ngfactory.js:904) AppView.detectChanges (view.js:425) DebugAppView.detectChanges (view.js:620) ViewContainer.detectChangesInNestedViews (view_container.js:67) View_TableComponent17.detectChangesInternal (/TableModule/TableComponent/component.ngfactory.js:962) AppView.detectChanges (view.js:425) DebugAppView.detectChanges (view.js:620) ViewContainer.detectChangesInNestedViews (view_container.js:67) View_TableComponent15.detectChangesInternal (/TableModule/TableComponent/component.ngfactory.js:1043) AppView.detectChanges (view.js:425)

问题

是什么原因导致父级更改时调用了ngAfterViewInit?组件被重新渲染 - 即从DOM中删除并替换吗?

我应该如何防止这种情况发生?即如何确保只调用一次ngAfterViewInit?

更新:在将组件C组件T都更改为使用ChangeDetectionStrategy.OnPush之后,afterViewInit仍会在任何更改时被调用。


1
这是由于 Angular 变更检测策略引起的。它会检查整个组件是否更新。您可以尝试更改检测策略,但这取决于您如何设置组件之间的绑定关系。最好的方法是使用 dumb / smart 组件和清晰的输入/输出。如果您依赖于路由出口并且无法使用输入/输出,则应该能够在不使用 ngAfterViewInit 的情况下使用服务来管理数据以实现您想要的效果。 - Alex Beugnet
@AlexBeugnet 我尝试使用 ChangeDetectionStrategy.OnPush,但无济于事 - 即使没有任何输入发生变化,仍然会触发变更检测。 - Daniel Cooke
1个回答

1
这可能是由于在子组件中使用了一些外部指令,其中还绑定了来自您提到的组件的值所致。
相关帖子:
{{link1:Angular 7:从订阅内部调用ChangeDetectorRef detectChanges()会导致无限循环}}

我不再能够访问这个代码库了,但如果你上传一个示例,它可能会帮助未来的某个人。谢谢! - Daniel Cooke
1
https://stackoverflow.com/questions/53467529/angular-7-changedetectorref-detectchanges-causes-infinite-loop-when-called-fr - Ravinder Payal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接