【发布时间】:2018-07-15 16:27:48
【问题描述】:
我正在使用 Angular 5.2.2,我想知道是否可以找到后代组件(嵌套深度 2+)。
例如:
- FirstLevelComponent (在我的应用程序中声明)
- SecondLevelComponent (第三方组件)
- ThirdLevelComponent (第三方组件)
FirstLevelComponent 模板:
<first-level-component>
<second-level-component></second-level-component>
</first-level-component>
SecondLevelComponent 模板:
<third-level-component></third-level-component>
我想在 FirstLevelComponent 中获取 ThirdLevelComponent 实例。
- 我尝试过使用@ViewChildren 和@ContentChildren,但没有成功。两者都返回一个空的 QueryList。
- 我无法更改 SecondLevelComponent 代码以公开 ThirdLevelComponent,因为它是第三方组件。
这个 plunker 演示了我正在尝试做的事情:https://plnkr.co/edit/9NsYmrsJMJEi0wofQReI?p=preview
编辑 (2018/02/06)
一个选项可能是继承 SecondLevelComponent 来公开 ThirdLevelComponent,但我不喜欢使用继承,它会被限制在一个深度级别。
-
经过一番检查,我最终创建了一个帮助程序来搜索后代组件。它使用 ViewContainerRef:
import * as NgCore from '@angular/core'; @NgCore.Injectable() export class FindDescendantsService { constructor() { } private findRecursive(container: any, type: any, results: any[]) { if (!container) { return; } if ('nodes' in container) { container.nodes.forEach(n => { if ('componentView' in n && n.componentView) { if (n.componentView.component instanceof type) { results.push(n.componentView.component); } this.findRecursive(n.componentView, type, results); return; } if ('viewContainer' in n && n.viewContainer && n.viewContainer._embeddedViews && n.viewContainer._embeddedViews.length) { n.viewContainer._embeddedViews.forEach(v => this.findRecursive(v, type, results)); return; } }); } } find(vcr: NgCore.ViewContainerRef, type: any) { var view = vcr['_view']; var results = []; this.findRecursive(view, type, results); return results; } }
然后在 FirstLevelComponent 我可以做:
ngAfterContentInit(){
var thirdLevelInstances = this.findDescendantsService.find(this.viewContainerRef, ThirdLevelComponent);
}
我不太舒服,因为它使用了一些私有变量,这些变量可能会在未来的 Angular 版本中改变名称/行为,但这满足了我现在的目标。我会等待一段时间,看看是否有更好的解决方案出现,如果没有,我认为这个助手可能是答案......
【问题讨论】:
标签: angular