如何将父组件注入子组件?

时间:2015-12-31 03:27:13

标签: angular angular2-di

我正在尝试将父组件注入子组件。我认为这很简单 - 只需在子代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: `<p>child</p>`
})
export class ChildComponent {
  constructor(private _parent:AppComponent) {}
}

AppComponent:

import {Component} from 'angular2/core';
import {ChildComponent} from './child.component';

@Component({
  selector: 'my-app',
  template: `{{title}} <child></child>
  `,
  directives: [ChildComponent]
})
export class AppComponent {
  title = "Angular 2 - inject parent";
  constructor() { console.clear(); }
}

Plunker

2 个答案:

答案 0 :(得分:44)

请参阅@ EricMartinez的comment获取答案。当A导入B和B导入A时,问题似乎是循环引用。

这是plunker,它使用两个文件而不是Eric's 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应该处理大多数用例。

     

我很抱歉,虽然我同意这在某些极少数情况下是痛苦的,但我没有看到任何方法,因此这个问题不可行,将会关闭。

嗯......我尝试注射父母的原因是因为我看到一个孩子与父母沟通的两种方式:

  1. 子节点定义输出属性并发出父节点订阅的事件
  2. 孩子注入父母(例如,Pane可能注入Tabs),然后可以调用父母的方法
  3. 我试图确定何时使用每种方法。 Miško听起来像是2.应该是罕见的。

    更新:我正在考虑更多...... 1.更好,因为孩子和父母之间的联系较少。使用1.孩子不需要知道(也可能不应该知道)父母的公共API /接口。
    在反方向(例如,父使用@ViewChild@Query现已弃用)来获取对子进程的引用,然后调用子进程上的方法),耦合很好,因为父级正在使用子组件,所以它需要知道子组件的公共API /接口:即输入和输出属性以及公共方法。

答案 1 :(得分:5)

您可以像这样简单地使用@Host装饰器:

import {Component, Host} from 'angular2/core';
....
constructor(@Host() private app: AppComponent)