@ContentChildren没有被填充

时间:2016-01-02 10:56:41

标签: angular

我有三个组件: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()方法中,我预计会填充内容子项。

我错过了什么吗?

[更新]

所以事实证明,当所有三个组件都在同一个文件中时,问题就存在了(参见我输出内容子项的控制台调试窗口):

Plnkr Demo of Issue

如果它们位于单独的文件中,则问题就会消失:

Plnkr Demo Working

通常,我只会将所有组件放在同一个文件中以供学习。但它让我很好奇。有谁知道为什么行为不同?

3 个答案:

答案 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,否则仅包含   直接的孩子。