2017-08-28 65 views
2

我有分量的层次结构:Angular 4 - 如何访问模板内部的嵌套组件?

App 
| 
Child 
| 
Input 

组件“儿童”接受一个模板从它的父这样的:

<my-child> 
    <ng-template> 
     <my-input></my-input> 
     <span>asdasdas</span> 
     <my-input></my-input> 
     <my-input></my-input> 
    </ng-template>  
</my-child> 

正如你可以在模板中看到有一些输入组件。现在我想要访问子组件列表中的<my-input>组件列表。我现在尝试的是使用@ ContentChildren/@ ViewChildren,但它似乎不工作。儿童组件的代码:

@Component({ 
    selector: 'my-child', 
    providers: [], 
    template: ` 
    <div> 
     <ng-template [ngTemplateOutlet]="inputTemplate" #input></ng-template> 
    </div> 
    `, 
    directives: [] 
}) 

export class Child implements OnInit, OnAfterViewInit { 

    @ContentChild(TemplateRef) inputTemplate: TemplateRef<any>; 

    @ViewChildren(InputComponent) inputComponents : QueryList<InputComponent>; 

    constructor() { 

    } 

    ngAfterViewInit(){ 
    //THIS SHOULD NOT BE EMPTY 
    console.log(this.inputComponents.toArray()); 
    } 
} 

请让我知道我做错了什么,以及如何/是否有可能获得由儿童组成InputComponents的列表。

也许我不应该在这里使用模板?有没有其他方法可以使此控件可定制,并仍然可以访问嵌套的InputComponents列表?

如果你想用它here's the plunker

回答

4

使用@ContentChildren(InputComponent)代替@ViewChildren()和订阅变化

ngAfterViewInit(){ 
    //THIS SHOULD NOT BE EMPTY 
    this.inputComponents.changes.subscribe(c => console.log(this.inputComponents.toArray())); 
    //console.log(this.inputComponents.toArray()); 
    } 

工作对我来说玩,但老实说,我不知道自己为什么@ContentChildren()代替@ViewChildren()正在工作。

Plunker link

+1

'ViewChildren'不起作用,因为内容DOM(在视图中不DOM)内组件 –

+0

TemplateRef使用ContentChild也必然和它的作品。我不知道订阅变更的能力。据我所知,它应该已经绑定在ngAfterViewInit中,但是由于这些组件嵌套在模板中,我认为它实际上是在后面发生的。感谢您的解决方案! – kubal5003

+0

是的,但'TemplateRef'实际上被传递了内容,但是模板被渲染到了组件中,并且我期望创建的组件成为子组件。是的,这就是原因。在ngOnInit或ngAfterViewInit中只有'TemplateRef'可用,'ngTemplateOutlet'只在这个变化检测周期完成后呈现。 –