我正在尝试将父组件注入子组件.我认为这很简单 - 只需在子代中指定/注入父组件constructor()
:
constructor(private _parent:AppComponent) {} // child component constructor
我收到以下错误:
EXCEPTION:无法解析ChildComponent(?)的所有参数.确保它们都具有有效的类型或注释.
我错过了什么?
ChildComponent:
import {Component} from 'angular2/core'; import {AppComponent} from './app.component'; @Component({ selector: 'child', template: `child
` }) export class ChildComponent { constructor(private _parent:AppComponent) {} }
AppComponent:
import {Component} from 'angular2/core'; import {ChildComponent} from './child.component'; @Component({ selector: 'my-app', template: `{{title}}`, directives: [ChildComponent] }) export class AppComponent { title = "Angular 2 - inject parent"; constructor() { console.clear(); } }
Plunker
请参阅@ EricMartinez的评论以获得答案.当A导入B和B导入A时,问题似乎是循环引用.
这是一个使用两个文件的plunker,而不是Eric的plunker中的一个文件.
我原来的plunker唯一的变化是在ChildComponent中:
import {Component, Inject, forwardRef} from 'angular2/core'; .... constructor(@Inject(forwardRef(() => AppComponent)) private _parent:AppComponent)
我不确定这是否会消除循环引用,因为A和B仍在相互导入,但它似乎有效.
另见https://github.com/angular/angular/issues/3216,Miško声明:
这[使用forwardRef()]不是用户友好的声明是JS的限制以及函数声明如何被提升.每当你有一个循环依赖,你将需要
forwardRef
:-(我只是没有看到它周围.我认为你不应该处理你的父母需要了解孩子和孩子需要了解父母的情况.
@Query
应该照顾大多数用例.我很抱歉,虽然我同意这在某些极少数情况下是痛苦的,但我没有看到任何方法,因此这个问题不可行,将关闭.
嗯...我尝试注射父母的原因是因为我看到一个孩子与父母沟通的两种方式:
子节点定义输出属性并发出父节点所订阅的事件
孩子注入父母(例如,Pane可能会注入Tabs),然后可以调用父母的方法
我试图确定何时使用每种方法.Miško听起来像2.应该是罕见的.
更新:我正在考虑更多...... 1.更好,因为孩子和父母之间的联系较少.使用1.孩子不需要知道(也可能不应该知道)父母的公共API /接口.
在相反的方向(例如,父使用@ViewChild
(@Query
现在已弃用)来获取对子进程的引用,然后调用子进程上的方法),耦合很好,因为父进程正在使用子组件,所以它需要知道子的公共API /接口:即输入和输出属性以及公共方法.
您可以像这样简单地使用@Host装饰器:
import {Component, Host} from 'angular2/core'; .... constructor(@Host() private app: AppComponent)