3

I've gone through quite a few other questions on SO related to this Angular feature and none of the solutions seem to help my scenario. I'm utilizing the Angular Material tree component, and am attempting to generate a component within a fully expanded node.

My Tree.component.html:

<ng-container class="tree-content">
    <mat-card>
        <mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
            <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
                <ng-container *ngIf="node.expandable">
                    <button mat-icon-button matTreeNodeToggle [attr.aria-label]="'Toggle ' + node.name" (click)="generateTreeContent(node, treeControl.isExpanded(node))">
                        <mat-icon class="dark">
                        {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
                        </mat-icon>
                    </button>
                    <p>{{node.name}}</p>
                </ng-container>
                <app-dynamic></app-dynamic>
            </mat-tree-node>
        </mat-tree>
    </mat-card>
</ng-container>

My ViewChildren decorator declaration in Tree.component.ts:

@ViewChildren(DynamicComponent) children: QueryList<DynamicComponent>;

My Dynamic.component.ts:

@Component({
    selector: 'app-dynamic',
    templateUrl: './Dynamic.component.html',
    styleUrls: ['./Dynamic.component.scss']
})
export class DynamicComponent implements OnInit, AfterViewChecked {
    constructor(public componentFactoryResolver: ComponentFactoryResolver, public viewContainerRef: ViewContainerRef, public changeDetectorRef: ChangeDetectorRef, public ref: ElementRef) {
    }
    ...
}

Every time I try to access children, the QueryList yields no results.

Other things I've tried:

  • Using the 'read' metadata property:

    *.ts:

    @ViewChildren('dynamic', { read: DynamicComponent }) children: QueryList<DynamicComponent>;
    

    *.html:

    <app-dynamic #dynamic></app-dynamic>
    
  • Subscribing to the QueryList changes via AfterViewInit():

    public ngAfterViewInit(): void { 
        this.children.changes.subscribe((c: QueryList<DynamicComponent>) =>
        {
          ...
        });
    }
    
  • Using ContentChildren (Both with and without the 'read' parameter):

    *.ts:

    @ContentChildren('dynamic', { read: DynamicComponent }) children: QueryList<DynamicComponent>;
    

    *.html:

    <app-dynamic #dynamic></app-dynamic>
    
  • Accessing the component via Directive:

    @ViewChildren('dynamic', { read: DynamicDirective }) children: QueryList<DynamicDirective>;
    
  • Accessing after forcing change detection:

    this.viewContainerRef.detectChanges();
    console.log(this.children.toArray());
    

What am I doing wrong here?

Josh Ray
  • 291
  • 2
  • 7
  • 1
    In your `Tree.component.ts` when are you trying to access the children? You cannot access them in `ngOnInit()` it will be `undefined` at that point. – Get Off My Lawn Jul 07 '21 at 01:09
  • I'm attempting to access the children in the generateTreeContent function called in the (click) defined in the html. And I've also tried in the change subscription of the children property, which should update with every change. – Josh Ray Jul 07 '21 at 01:15
  • I assume that `` is in the inspector is that correct? – Get Off My Lawn Jul 07 '21 at 01:22
  • Yes, I can see the tag in the inspector. – Josh Ray Jul 07 '21 at 01:30
  • When you subscribe to changes, do you ever get the subscription to execute? Even if you expand the tree? – Donald Duck Jul 07 '21 at 05:09
  • it's looks like work well, I've wrote an example in stackblitz:https://stackblitz.com/edit/angular-91kw8b?file=src%2Fapp%2Ftree-flat-overview-example.html (What about your function `generateTreeContent`? – Eliseo Jul 07 '21 at 06:54

0 Answers0