我有三个组件:App,Parent和Child:
应用组件
@Component({
selector: 'app',
directives: [Parent,Child],
template: '<parent><child>hi</child><child>there</child></parent>'
})
export class AppComponent {
constructor() {
}
}
父组件
@Component({
selector: 'parent',
template: '<div><h1>Parent</h1><ng-content></ng-content></div>'
})
export class Parent {
@ContentChildren(Child) children: QueryList<Child>;
ngAfterContentInit() {
console.log(this.children);
}
}
子组件
@Component({
selector: 'child',
template: '<div><h1>Child</h1></div>'
})
export class Child {
}
正如您在Parent组件中看到的那样,我尝试使用@ContentChildren
获取子组件列表,使用Child
类型作为选择器。但是,这似乎不起作用 - 内容子列表始终未定义。
在ngAfterContentInit()
方法中,我预计会填充内容子项。
我错过了什么吗?
[更新]
所以事实证明,当所有三个组件都在同一个文件中时,问题就存在了(参见我输出内容子项的控制台调试窗口):
如果它们位于单独的文件中,则问题就会消失:
通常,我只会将所有组件放在同一个文件中以供学习。但它让我很好奇。有谁知道为什么行为不同?
答案 0 :(得分:21)
您需要使用forwardRef来引用尚未定义的类。见this plunk。请记住ES6 classes are not hoisted。
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider
.when('/', '/homeB')
.otherwise('/homeB');
$stateProvider
.state('tabs', {
abstract: true,
url: '/',
template: '<my-tab-b></my-tab-b>',
onEnter: function(){console.log("enter");}
})
});
UPD Mark Rajcok在angular2中指出了一篇关于前向引用的优秀文章(见下文评论)。必读:thoughtram.io Forward references in Angular 2。
答案 1 :(得分:0)
如果子组件在构造函数中引用父组件,也会发生这种情况; Angular不喜欢圆形参考!
我只需要选择一种方法来进行父级/子级通信:要么使用ContentChildren
,要么使用子级constructor
中的父级组件。
@Component()
export class Parent {
@ContentChildren(Child)
private children: QueryList<Child>;
}
@Component()
export class Child {
constructor(
// !! Remove the following line to make the ContentChildren "work" again.
@Optional() parent: Parent
) { }
}
答案 2 :(得分:0)
您需要添加{ descendants: true }
来包含嵌套子级,
@Component({
selector: 'parent',
template: '<div><h1>Parent</h1><ng-content></ng-content></div>'
})
export class Parent {
@ContentChildren(Child, { descendants: true }) children: QueryList<Child>;
ngAfterContentInit() {
console.log(this.children);
console.log(this.children.length);
}
}
descendants-包含所有后代为True,否则仅包含 直接的孩子。