13
votes

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?

3

3 Answers

18
votes

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.

5
votes

Just use return false;
here is code which i have used for prevent default

  @HostListener('click') open(){
      this._isOpen = !this._isOpen;
      return false;
  }

And for stopPropagation

 @HostListener('click', ['$event'])
 onClick(e) {
  alert("we have performed click");
  e.stopPropagation();
 }
1
votes

I implemented event.preventDefault like this

export class ObserveComponent{
   onSubmit(event:Event){
     event.preventDefault();
  }
}

stopped page reload every time I tried to access value of a key which is not exist in the object