Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to listen to children elements events in a directive?

Since there is no template, what's the best way to listen to child elements event in a directive? Is it possible with HostListener? If not, is there any other way?

There's also this similar question: How to listen for child event from parent directive in Angular2, but the suggested approach does not solve my problem, as my directive and child element aren't in the same template (directive is on host).

Cheers!

Edit #1

This is how I'm currently doing it (there has to be a better way):

First injecting ElementRef into my directive:

constructor(private elView: ElementRef) {}

Then binding with jQuery (or plain JS):

$(this.elView.nativeElement)
.on('drag', '#childId', this.slide.bind(this))
like image 529
Maxime Dupré Avatar asked Nov 17 '16 15:11

Maxime Dupré


People also ask

How do you listen for events in a component Angular?

To listen to an event in AngularJs, use event handling directives like ng-click , ng-change etc.

Which of the following is used for listening to user events in Angular?

@HostListener is Angular's decorator method that's used for listening to DOM events on the host element of both component and attribute directives.

What is host listener?

HostListenerlinkDecorator that declares a DOM event to listen for, and provides a handler method to run when that event occurs.


2 Answers

If the event you want to listen to is a native DOM event that bubbles, then you can just use @HostListener()

@HostListener('click', ['$event'])
handleClick(event) {
  // handle event
}

If they are outputs of child components, you can query them and subscribe to their outputs

@ContentChildren(ChildComponent) children:QueryList<ChildComponent>;

ngAfterContentInit() {
  this.children.toArray().forEach((item) => {
    item.someOutput.subscribe(...);
  });
}

or you can use the approach used in the answer you linked to in your question.

like image 156
Günter Zöchbauer Avatar answered Oct 19 '22 22:10

Günter Zöchbauer


You might consider to make your components communicate with each other via the service-class.

// service class
class Service {
  private someEventSource = new Subject();
  public someEvent = this.someEventSource.asObservable();

  public invokeAnEvent (data: string) {
    this.someEventSource.next(data);
  }
}

// parentComponent class
Service.someEvent.subscribe(data => {
  console.log(data);
});

// childComponent class
Service.invokeAnEvent('some data to pass');

From Angular documentation:
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

like image 21
Konstantin Vitkovsky Avatar answered Oct 19 '22 21:10

Konstantin Vitkovsky