Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4 - how do I get access to nested components inside a template?

Tags:

angular

I have a hierarchy of components:

App
|
Child
|
Input

The component "Child" accepts a template from it's parent like this:

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

As you can see in the template there's a number of input components. Now I would like to get an access to the list of <my-input> components from the child component. What I tried now was to use the @ContentChildren/@ViewChildren, but it doesn't seem to work. The code of Child component:

@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());
  }
}

Please let me know what I'm doing wrong and how/if it is possible to get a list of InputComponents from the Child component.

Maybe I shouldn't be using a template here at all? Is there any other way to make this control customisable and still be able to access a list of nested InputComponents?

In case you want to play with it here's the plunker

like image 619
kubal5003 Avatar asked Aug 28 '17 09:08

kubal5003


1 Answers

Using @ContentChildren(InputComponent) instead of @ViewChildren() and subscribing to changes

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

worked for me, but honestly I don't know myself why @ContentChildren() instead of @ViewChildren() is working.

Plunker link

like image 77
Günter Zöchbauer Avatar answered Oct 20 '22 17:10

Günter Zöchbauer