Search code examples
angularangular-componentsviewchild

Why does @ViewChildren pick the template only for the first time?


I am creating an app where I want to render the buttons inside a table using a component. So, I created a component where I'v kept the button template and am using @ViewChildren to get the template and ViewContainerRef to apply the component to the template. However, only the first row is getting set and not the other. I can't figure out the reason for this? Here's what I'v been trying: https://stackblitz.com/edit/angular-rsxvbt


Solution

  • Your solution doesn't work because you are using a single reference with @ViewChild, but you are inside an ng-For and so you have to manage a QueryList of ViewContainerRef with @ViewChildren.

    Try to change your code as follow:

    replace:

    @ViewChild("dynamic", { static: false, read: ViewContainerRef }) ref;
    @ViewChildren("dynamic") private button: QueryList<"dynamic">;
    

    with:

    @ViewChildren('dynamic', {read: ViewContainerRef}) public widgetTargets: QueryList<ViewContainerRef>;
    

    so that we can have a ref to every children.

    replace:

    ngAfterViewInit() {
        const componentFactory = this._componentFactoryResolver.resolveComponentFactory(
          HelloComponent
        );
        const ref = this.ref.createComponent(componentFactory);
        
      }
    

    with:

    ngAfterViewInit() {
        const targets = this.widgetTargets.toArray();
        for (let i = 0; i < targets.length; i++) {
            let target = targets[i];
            if(target) {
                let componentFactory = this._componentFactoryResolver.resolveComponentFactory(HelloComponent);
                let cmpRef: any = target.createComponent(componentFactory);
            }
        }
      }
    

    so that we can cycle over our list of refs and create our component on the fly

    stackblitz

    All the best.