Angular2 EventEmitter and preventDefault()

seraph picture seraph · Mar 1, 2016 · Viewed 33.1k times · Source

Is there a way in Angular2 to somehow prevent the default for events using the EventEmitter?

I have the following scenario:

import {Component, Output, EventEmitter} from 'angular2/core'

@Component({
  selector: 'my-component',
  template: `<button (click)="clickemitter.emit($event); onClick($event)" [style.color]="color"><ng-content></ng-content></button>`
})
export class MyComponent {
  @Output clickemitter: EventEmitter<MouseEvent> = new EventEmitter();

  private color: string = "black";

  constructor() {

  }

  private onClick(event: MouseEvent): void {
    if(!event.defaultPrevented) //gets called before the observers of clickemitter
      this.color = "red";
    else this.color = "blue";
  }
}

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <my-component (clickemitter)="$event.preventDefault()">Hello Angular</my-component>
  `,
  directives: [MyComponent]
})
export class App {
  constructor() {

  }
}

I made a Plunker for this, too: https://plnkr.co/edit/yIoF1YgvkiZLBPZ6VHTs?p=preview

The Problem If i click on the button the color of the button wouldn't turn blue as it should but it turns red instead. This might be because EventEmitter.emit()/next() seem to work asynchronous. I tried to solve this problem by also subscribing my onClick() method at the emitter and just call clickemitter.emit($event) in my button (click) event handler. This would work for the Plunker Demo when i did it in ngAfterInit(). But what if someone subscribes to the clickemitter later? My component would get called before that observer again and my component would be inconsistent.

The Question How can i ensure that my component onClick() handler will get called at the very last to guarantee that no other observer can prevent the default behavior afterwards? Or is there a complete different way of achieving my goal?

Answer

Jatin Roy picture Jatin Roy · Jun 19, 2017

To solve this problem use this in your html template

<button (click)="clickemitter(a,b,c); $event.stopPropagation();" 
        [style.color]="color" >
        <ng-content></ng-content>
</button> 

As $event.stopPropagation(); works to stop default click event and your button only call event that written in (click)="...." which is clickemitter.emit(a,b,c)

Maybe this is help full to you. Thank you.