Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@ContentChildren not picking up items inside custom component

I'm trying to use @ContentChildren to pick up all items with the #buttonItem tag.

@ContentChildren('buttonItem', { descendants: true })

This works when we have the ref item directly in the parent component.

<!-- @ContentChildren returns child item -->
<parent-component>
  <button #buttonItem></button>
<parent-component>

But, if the element with the #buttonItem ref is wrapped in a custom component, that does not get picked by the @ContentChildren even when I set the {descendants: true} option.

<!-- @ContentChildren returns empty -->
<parent-component>
  <child-component-with-button-ref></child-component-with-button-ref>
<parent-component>

I have created a simple StackBlitz example demonstrating this.

like image 314
nipuna777 Avatar asked Dec 06 '18 06:12

nipuna777


2 Answers

Doesn't appear to be a timeline for a resolution of this item via github... I also found a comment stating you cannot query across an ng-content boundary.

https://github.com/angular/angular/issues/14320#issuecomment-278228336

Below is possible workaround to get the elements to bubble up from the OptionPickerComponent.


enter image description here


in OptionPickerComponent count #listItem there and emit the array AfterContentInit

 @Output() grandchildElements = new EventEmitter();     
 @ViewChildren('listItem') _items

  ngAfterContentInit() {
    setTimeout(() => {
        this.grandchildElements.emit(this._items)
    })
  } 

Set template reference #picker, register to (grandchildElements) event and set the $event to picker.grandchildElements

 <app-option-picker #picker [optionList]="[1, 2, 3]" (grandchildElements)="picker.grandchildElements = $event" popup-content>

Create Input on PopupComponent to accept values from picker.grandchildElements

@Input('grandchildElements') grandchildElements: any

In app.component.html accept picker.grandchildElements to the input

<app-popup [grandchildElements]="picker.grandchildElements">

popup.component set console.log for open and close

open() {
    if (this.grandchildElements) {
      console.log(this.grandchildElements);
    }
    else {
      console.log(this.childItems);
    }

 close() {
     if (this.grandchildElements) {
      console.log(this.grandchildElements);
    }
    else {
      console.log(this.childItems);
    }

popup.component change your ContentChildren back to listItem

@ContentChildren('listItem', { descendants: true }) childItems: Element;

popup.component.html set header expression

<h3>Child Items: {{grandchildElements ? grandchildElements.length : childItems.length}}</h3>

Stackblitz

https://stackblitz.com/edit/angular-popup-child-selection-issue-bjhjds?embed=1&file=src/app/option-picker/option-picker.component.ts

like image 51
Marshal Avatar answered Oct 10 '22 09:10

Marshal


I had the same issue. We are using Kendo Components for angular. It is required to define Columns as ContentChilds of the Grid component. When I wanted to wrap it into a custom component and tried to provide additional columns via ng-content it simply didn't work.

I managed to get it working by resetting the QueryList of the grid component AfterViewInit of the custom wrapping component.

  @ViewChild(GridComponent, { static: true })
  public grid: GridComponent;

  @ContentChildren(ColumnBase)
  columns: QueryList<ColumnBase>;

  ngAfterViewInit(): void {
    this.grid.columns.reset([...this.grid.columns.toArray(), ...this.columns.toArray()]);
    this.grid.columnList = new ColumnList(this.grid.columns);
  }
like image 25
cyberblast Avatar answered Oct 10 '22 09:10

cyberblast