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

How do I inject a parent component into a child component?

我正在尝试将父组件注入子组件。我认为这会很简单——只需 specify/inject 子组件中的父组件 constructor():

constructor(private _parent:AppComponent) {}   // child component constructor

我收到以下错误:

EXCEPTION: Cannot resolve all parameters for ChildComponent(?). Make sure they all have valid type or annotations.

我错过了什么?

子组件:

import {Component} from 'angular2/core';
import {AppComponent} from './app.component';

@Component({
  selector: 'child',
  template: `<p>child</p>`
})
export class ChildComponent {
  constructor(private _parent: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

请参阅@EricMartinez 的 以获得答案。问题好像是A导入B,B导入A时的循环引用。

这里是 plunker that uses two files instead of the one file that is in 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 指出:

This [not user-friendly declaration using forwardRef()] is a limitation of JS and how the function declarations get hoisted. Whenever you have a circular dependency you will need forwardRef :-( I just don't see a away around it.

I would argue that you should not be in situation where your parent needs to know about the children and children need to know about parent. @Query should take care of most of the use cases.

I am sorry, but while I agree this is a pain in some rare cases, I don't see a way out of it, and hence this issue is not actionable, will close.

嗯...我尝试注入 parent 的原因是因为我看到 child 与 parent 通信的两种方式:

  1. child 定义输出属性并发出事件,parent 订阅
  2. child 注入 parent(例如,Pane 可能注入 Tabs),然后可以调用 parent
  3. 上的方法

我试图确定何时使用每种方法。 Miško 让它听起来像 2。应该很少见。

更新: 我正在考虑更多... 1. 更好,因为 child 和 parent 之间的耦合较少.对于 1. child 不需要知道(并且可能不应该知道)parent 的 public API/interface。
在相反方向(例如,parent 使用 @ViewChild@Query 现在已弃用)获取对 child 的引用,然后调用方法child), 耦合没问题,因为parent使用的是child组件,所以需要知道public API/interface的child:即输入和输出属性和 public 方法。

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

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