当我拥有嵌套在根组件providing
下的组件时,我无法实例化我的应用程序,该组件是它在其构造函数中使用的组件。
import {Component, Injectable} from 'angular2/core';
@Component()
export class GrandChild(){
constructor () {
this.hello = "hey!"
}
}
@Component({
providers: [GrandChild]
})
@Injectable()
export class Child {
constructor(public grandchild: GrandChild) {
this.grandchild = grandchild;
}
}
@Component({
providers: [Child],
template: `Everything rendered fine!`,
selector: 'app'
})
export class App {
kid: Child;
constructor(public child: Child) {
this.kid = child;
}
}
EXCEPTION: No provider for GrandChild! (App -> Child -> GrandChild)
我想知道为什么这种行为是非法的。假设我想在我的GrandChild
课程中使用Child
课程,只需在Child
课程中引用App
课程。这似乎是不可能的。
创建provide
层次结构的正确方法是什么?
非常感谢。
答案 0 :(得分:1)
您可以将父组件直接注入组件,而无需将其指定到组件提供程序中。为此,您需要将组件用于其他组件并将其设置为directives
属性:
@Component({
selector: 'child',
template: `
<div></div>
`
})
export class Child {
constructor(@Inject(forwardRef(() => App)) parent: App) {
}
}
@Component({
directives: [Child],
template: `
Everything rendered fine!
<child></child>
`,
selector: 'app'
})
export class App {
constructor() {
}
}
您的示例中有点奇怪的是,您没有为组件selector
和template
定义Child
和GrandChild
属性。它们真的是组件吗?
在你的样本中,你做错了事。如果要从父组件获取子组件的实例,则需要利用@ViewChild
装饰器通过注入从父组件引用子组件:
import { Component, ViewChild } from 'angular2/core';
(...)
@Component({
selector: 'my-app',
template: `
<h1>My First Angular 2 App</h1>
<child></child>
<button (click)="submit()">Submit</button>
`,
directives:[App]
})
export class AppComponent {
@ViewChild(SearchBar) searchBar:SearchBar;
(...)
someOtherMethod() {
this.searchBar.someMethod();
}
}
这是更新的plunkr:http://plnkr.co/edit/mrVK2j3hJQ04n8vlXLXt?p=preview。
您可以注意到也可以使用@Query
参数装饰器:
export class AppComponent {
constructor(@Query(SearchBar) children:QueryList<SearchBar>) {
this.childcmp = children.first();
}
(...)
}
当你拥有@Injectable
时,你可能会注意到你不需要@Component
装饰者......
答案 1 :(得分:1)
您可以通过向GrandChild
的提供商添加App
来解决此问题。
但是,当您将它们用作服务时,我不明白为什么您将Child
和GrandChild
注释为@Component
。我想这就是你真正想做的事情。
@Injectable()
export class GrandChild(){
constructor () {
this.hello = "hey!"
}
}
@Injectable()
export class Child {
tire: string;
constructor(public grandchild: GrandChild) {
this.grandchild = grandchild;
}
}
@Component({
providers: [Child, GrandChild],
template: `Everything rendered fine!`,
selector: 'app'
})
export class App {
thread: Thread;
selected: boolean = false;
kid: Child;
constructor(public child: Child) {
this.kid = child;
}
}
查看更新的plnkr demo。