Angular2 Click Processing Modification Directive

I am trying to write an Angular2 attribute directive to change the behavior of some elements. More specifically, I want to apply an attribute to certain elements that have click handlers and prevent the execution of a related function under certain conditions.

So now I have an element, for example:

<button (click)="onClick(param1, param2)"></button> 

onClick is a function declared on a component in which the host button element does some work.

I would like to write something like:

 <button (click)="onClick(param1, param2)" online-only></button> 

and have such a directive as:

 @Directive({ selector: '[online-only]', }) export class OnlineOnlyDirective { @HostListener('click', ['$event']) onClick(e) { if(someCondition){ e.preventDefault(); e.stopPropagation(); } } } 

But first, the click handler is executed, thereby preventing my directive from stopping its execution.

The second approach that I was thinking about was to replace (click) my own handler eg ([onlineClick] = "onClick") and execute the passed function when the directive deems necessary, but in this way I can not pass the parameters to the onClick function and a little weirder look.

Do you have any thoughts on something like this?

+7
javascript angular ionic2 angular2-directives
source share
3 answers

I don't know how to get Angular to execute a specific event handler. A workaround could be to use a custom event, for example:

 <button (myClick)="onClick(param1, param2)" online-only></button> 
 @Directive({ selector: '[myClick]', }) export class OnlineOnlyDirective { @Output() myClick: EventEmitter = new EventEmitter(); @HostListener('click', ['$event']) onClick(e) { if(someCondition){ e.preventDefault(); e.stopPropagation(); } else { this.myClick.next(e); } } } 
+11
source share

It is not yet possible for you to want it (just using the binding). This is due to the fact that all events registered through the Angular binding → by (click), @HostListner, are proxied through one listener. That calling stopPropagation or more correctly in this case stopImmediatePropagation does not work, since you no longer have separate event listeners. For more information, refer to this issue: https://github.com/angular/angular/issues/9587 .

+1
source share

I recently went through something similar that I wanted to do, and the proposed answer did not work, maybe because I had a click handler on the user component. This is what I did.

 <button (myClick)="onClick(param1, param2)" online-only></button> 

Or

 <my-cmp (myClick)="onClick(param1, param2)" online-only></my-cmp> 

A directive might look like this:

 @Directive({ selector: '[online-only]', }) export class OnlineOnlyDirective implements OnInit { constructor(private el: ElementRef) { } ngOnInit() { if (someCondition) { this.el.nativeElement.removeAllListeners('click'); } } } 

This will remove the click event listener on the component or element. It will not be someCondition , so if some someCondition change, there should be a way to get someCondition back. I don't need this use case though.

Refresh

This worked for me in development, but did not work for me when the code was minimized in a production environment.

+1
source share

All Articles