在我看来,在几乎所有我们指定组件@Input
s / @Output
s的情况下,我们都可能没有任何@Input
s / @Output
s,而是使用@ViewChild
直接访问组件属性。例如,考虑寻呼机的以下两种可能的API:
选项1:将当前页面和总页面公开为@Input
,为下一个/上一个页面请求设置事件发射器(@Output
s)。
<pager
[currentPage]="..."
[totalPages]="..."
(requestsNextPage$)="..."
(requestsPreviousPage$)="..."
></pager>
选项2:为当前页面和总页面设置简单属性,为下一个/上一个页面请求设置可观察对象/主题,并通过@ViewChild
进行公开。
<pager></pager>
@ViewChild(PagerComponent)
pager: PagerComponent
pager.currentPage = ...
pager.totalPages = ...
pager.requestsNextPage$.subscribe(...)
pager.requestsPreviousPage$.subscribe(...)
我的问题是,如果在大多数情况下这两种选择都同样可行,那么什么是首选/最佳实践?为什么?
答案 0 :(得分:2)
您描述的两种情况并不相同。
情况A:
<child [property]="value"></child>
子组件将使用“属性=值”呈现,并且每当“值”更改时,子组件的视图将被更新(因为输入属性已更改)。
情况B:
<child></child>
child.property = value;
子组件使用“属性=值”呈现(取决于此代码在生命周期中的运行时间),并且进一步的更改不会反映在子组件的视图中。
如果您只是设置一个永不更改的初始值,则 对于这两种情况可能是等效的。但是,这不太可能是您想要做的。 Angular在重用组件方面非常积极,其使用的条件之一就是@Input属性。我遇到了这样的麻烦:由于这种行为,组件被重用而不是删除并重新创建,因此理解和调试它会非常令人沮丧。
答案 1 :(得分:0)
使用@Input()时,每次更改ngOnChanges()都会被调用,这可能会引起更多噪音。
使用ViewChild()属性装饰器来配置视图查询。变更检测器在视图DOM中查找与选择器匹配的第一个元素或指令。如果视图DOM更改,并且有一个新的子项与选择器匹配,则该属性会更新。
所以ViewChild()不会产生这种噪音,它是@Input()的首选方式