如何将父组件注入子组件?
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(); }
}
请参阅@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 通信的两种方式:
- child 定义输出属性并发出事件,parent 订阅
- child 注入 parent(例如,Pane 可能注入 Tabs),然后可以调用 parent
上的方法
我试图确定何时使用每种方法。 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)
我正在尝试将父组件注入子组件。我认为这会很简单——只需 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(); }
}
请参阅@EricMartinez 的
这里是 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 通信的两种方式:
- child 定义输出属性并发出事件,parent 订阅
- child 注入 parent(例如,Pane 可能注入 Tabs),然后可以调用 parent 上的方法
我试图确定何时使用每种方法。 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)