Angular 5 access divs list using @ViewChildren
Asked Answered
D

2

30

I want to fetch all divs starting with the id 'div'. To do so, i use @ViewChildren but i'm not able to access the divs because i have an empty array , why ?

My template

<div id="div-1">Div 1</div>
<div id="div-2">Div 2</div>
<input type="button" (click)="getDivs()">

Component

@ViewChildren('div') divs: QueryList<any>;
divList : any[];

getDivs(){ 
   this.divList = this.divs.filter(x => x.id.lastIndexOf('div-', 0) === 0);  
   console.log(this.divList);  
      // this.divList return an empty array but i should have two results  
}
Demesne answered 26/10, 2018 at 21:38 Comment(0)
T
66

As mentioned in this detailed answer, the valid selectors for ViewChildren include component types, directive types, and template reference variables. You cannot retrieve DOM elements with ViewChildren using CSS selectors like HTML element types (e.g. div) or class names.

One way to make it work in your case is to generate the div elements with an ngFor loop, and associate a template reference variable #divs to them:

<div #divs *ngFor="let item of [1,2]" [id]="'div-' + item">Div {{item}}</div>
<button (click)="getDivs()">Get divs</button>

You can then retrieve them in code with ViewChildren, using the template reference variable:

@ViewChildren("divs") divs: QueryList<ElementRef>;

getDivs() {
  this.divs.forEach((div: ElementRef) => console.log(div.nativeElement));
}

See this stackblitz for a demo.

Troth answered 26/10, 2018 at 21:54 Comment(1)
I'm using Angular 8, and I needed to modify the @ViewChildren statement as follows: @ViewChildren("divs", { read: ElementRef }) divs: QueryList<ElementRef>;Flattish
R
4

I was able to achieve needed result by creating custom directive and querying it like this:

import { Directive, ElementRef, ViewChildren, Component, AfterViewInit, QueryList } from "@angular/core";

@Directive({selector: 'table th'})
export class DatatableHeadersDirective {
  nativeElement: HTMLTableHeaderCellElement = null;
  constructor(el: ElementRef) {
    this.nativeElement = el.nativeElement;
  }
}

@Component({
  selector: 'selctorname',
  templateUrl: 'htmlURL',
  styleUrls: ['styleURL'],
})
export class AwesomeDatatableComponent implements AfterViewInit {
  @ViewChildren(DatatableHeadersDirective) children: QueryList<DatatableHeadersDirective>;;

  ngAfterViewInit(){
    console.log(this.children.map(directive => directive.nativeElement))
  }
}
Revivalist answered 16/1, 2021 at 16:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.