Angular2 - catch/subscribe to (click) event in dynamically added HTML
Asked Answered
N

1

9

I'm attempting to inject a string that contains a (click) event into the Angular2 template. The string is dynamically retrieved from the back-end much after the DOM is loaded. No surprise here that Angular won't recognize the injected (click) event.

Example template:

<div [innerHTML]="test"></div>

Example string given from back-end:

var test = "When ready, <span (click)=\"itemClick($event)\">click me</span>."

Example function call in the Angular component:

itemClick(event) {
   debugger;
}


My next guess would be to try having Angular subscribe or catch a plain-old javascript event, so the string would then be:
var test = "When ready, <span onClick=\"itemClick($event)\">click me</span>."

Sure enough, I get an error that itemClick is not defined, so I know it's looking for that javascript function.

So question: How can I get Angular2 to subscribe to this event or function?

Nahshun answered 20/3, 2016 at 17:6 Comment(0)
F
21

Declarative event binding is only supported in static HTML in a components template.
If you want to subscribe to events of elements dynamically added, you need to do it imperatively.

elementRef.nativeElement.querySelector(...).addEventListener(...)

or similar.

If you want to be WebWorker-safe, you can inject the Renderer

constructor(private elementRef:ElementRef, private renderer:Renderer) {}

and use instead

this.renderer.listen(this.elementRef.nativeElement, 'click', (event) => { handleClick(event);});

to register an event handler.

see also Dynamically add event listener in Angular 2

Fillmore answered 20/3, 2016 at 17:13 Comment(11)
I would just like to add that since the above code is executed inside a component (as evidenced by the fact that Günter is using ElementRef and/or Renderer), it is executed inside the Angular zone, hence after the click event handler fires, Angular change detection will always run (as desired). (If you were to instead attach the event handler outside Angular, it would not work as desired.)Salvia
Do we need to unregister the listener in ngOnDestroy() if we use addEventListener() or listen()?Salvia
I assume - yes, but I'm never sure about this. Usually if you request a resource imperatively, you're responsible to release to be on the safe side.Calumny
Apparently Renderer.listen() will return a function that will remove the listener (that's handy). See Eric's answer for an example: https://mcmap.net/q/145969/-dynamically-add-event-listenerSalvia
Thank you! I am getting exact same issue and I am not quiet clear how to add a listener for click event on a specific span . For example the one asked in the question.Elidiaelie
Just replace ... in elementRef.nativeElement.querySelector(...).addEventListener() with a CSS selector that matches the element - like 'span'Calumny
what is e mentioned there?Bettinabettine
@Bettinabettine it should be event. Thanks for the hint - fixed.Calumny
#44408271Bettinabettine
@MarkRajcok so, is there a need to unregister them in ngOnDestroy()Foreman
This won't work when you have duplicate generated html for example close buttons on thumbnails.Superpose

© 2022 - 2024 — McMap. All rights reserved.