Dachstein
Dachstein

Reputation: 4272

Angular Directive - Accessing children

Let's say I have a parent and inside generating children with an ngFor loop. I want to place a directive on the parent which has access to all its childs.

<div appMyDirective>
    <div *ngFor="..."></div>
</div>

How to get access to all children from that directive (e.g. something like QueryList) ?

NOTE: I need to keep updated when a new child element is inserted.

@Directive({
   selector: '[appMyDirective]'
})
export class MyDirective {

  constructor(private elem: ElementRef) { }

  // How to access all children (DOM Elements) and stay updated about changes???
}

Upvotes: 1

Views: 2981

Answers (1)

alt255
alt255

Reputation: 3566

Angular directives can not use ViewChild or ViewChildren. Instead you can access the native dom element using Dependency Injection inside the directive and use MutationObserver api to listen for changes. for example see the attached code snippet.

Full Example

import { Directive, ElementRef } from '@angular/core';

@Directive({
  selector: '[appWatcher]'
})
export class WatcherDirective {
  observer
  constructor(private elem: ElementRef) {
    console.log('Watcher Attached', elem)
  }

  ngOnInit() {
    var observerOptions = {
      childList: true,
      attributes: true,
      subtree: true //Omit or set to false to observe only changes to the parent node.
    }
    this.observer = new MutationObserver(this.callback);
    this.observer.observe(this.elem.nativeElement, observerOptions);

  }

  private callback(mutationList, observer) {
    mutationList.forEach((mutation) => {
      switch (mutation.type) {
        case 'childList':
          /* One or more children have been added to and/or removed
             from the tree; see mutation.addedNodes and
             mutation.removedNodes */
          console.log('Child Added or removed');
          break;
      }
    });

  }
  ngOnDestroy() {
    this.observer.disconnect();
  }

}

Upvotes: 2

Related Questions