Angular : Dynamic event
Angular processes the template when the component is compiled. Any HTML added later is not compiled again and bindings are ignored.
You can use the following :
constructor(private elRef:ElementRef) {}
ngAfterViewInit() {
// assume dynamic HTML was added before
this.elRef.nativeElement.querySelector('button').addEventListener('click',
this.onClick.bind(this));
}
your use case :
public createElement(){
const ele = '<button>click me</button>';
this.elRef.nativeElement.querySelector('button').addEventListener('click',
this.methodName.bind(this));
info.setInfoContentHTML(ele);
}
public methodName(){
console.log('event called');
}
How to create button dynamically with click event in angular 2+
I strongly recommend not using [innerHTML]
for this. It is not meant for this purpose and not the "angular way" at all.
This is the most preferable way to solve your issue and "the angular way".
component.ts
export class AppComponent {
public buttonsTexts:Array<string> = ['First button'];
public addButton(index:number):void {
this.buttonsTexts = [...this.buttonsTexts, `button ${index}`];
}
}
template.html
<button
*ngFor="let buttonText of buttonsTexts; let i = index;"
(click)="addButton(i)">{{buttonText}}</button>
StackBlitz
Using Renderer2Use this only if *ngFor
is not able to solve your issue because of some requirements that we don't know.
component.ts:
export class AppComponent implements AfterViewInit {
@ViewChild('inserttarget', {static: false})
public insertTarget:ElementRef; // use this if you want to insert inside a specific element in your template
constructor(
private renderer:Renderer2,
private el:ElementRef // use this if you want to insert into your template's root
) {
}
public ngAfterViewInit():void {
this.addNewButton();
}
public addNewButton():void {
const button = this.renderer.createElement('button');
const buttonText = this.renderer.createText('Click me');
this.renderer.appendChild(button, buttonText);
this.renderer.appendChild(this.insertTarget.nativeElement, button); // use this.el.nativeElement to insert into template root
this.renderer.listen(button, 'click', () => this.addNewButton());
}
}
template.ts
<p #inserttarget>
Some text
</p>
Here a working StackBlitz.
Bind events to dynamically created html in Angular
Since you don't have access to the dynamically generated HTML the choices you have are two:
- Fork the library's code and add the event listener. Then use the forked code in your application. I would advise strongly against this tho. You would need to maintain another library and this can lead to a lot of errors and a lot of overhead
- Add an event listener directly to the generated HTML element. This would be a more direct solution without much overhead.
So expanding on 2.:
You would need to use listen from Renderer2 from angular, which is detailed in docs here and in this answer as well. In sort you need to create something like this:
let global = this.renderer.listen('document', 'click', (evt) => {
console.log('Clicking the document', evt);
})
let simple = this.renderer.listen(this.myButton.nativeElement, 'click', (evt) => {
console.log('Clicking the button', evt);
});
Please also keep in mind that the element should already be rendered for this to work, so you need to place this code either inside the ngAfterViewInit() lifecycle hook or set a timeout (not advised - you don't want to have to debug race conditions as well).
As a note, please also see the plunker of the linked issue to see the full implementation.
Adding a click event to a dynamically created html element using angular2
You can add an event listener to the body which will process the event on your specified constraints like:
document.querySelector('body').addEventListener('click', (event)=> {
if (event.target.id.toLowerCase() == `remove_${parameter.name}`) {
this.removeParameter(`${parameter.name}`);
}
});
Note: Direct DOM access is discouraged in Angular2 and it's not a aot-friendly code.
Related Topics
Typeerror: Router.Use() Requires Middleware Function But Got a Object
Javascript: Open Several Urls With One Button Click
Accessing Variables from Other Functions Without Using Global Variables
How to Access Session Variables and Set Them in JavaScript
How to Output a Variable from JavaScript to HTML
Check If Json Response Data Is Empty
Keep Selected Dropdown Result After Refreshing Page, Jquery
How to Make One Observable Sequence Wait for Another to Complete Before Emitting
How to Get Full Path of Selected File on Change of <Input Type='File'> Using Javascript, Jquery-Ajax
Bootstrap 4 Dropdown Menu Not Working
Angularjs:Ng-Model Binding Not Updating When Changed With Jquery
Way to Access Const from Another Component in React
Call Js Function After Div Is Loaded
How to Add or Update a Query String Parameter
Disable Chrome Strict Mime Type Checking
Jquery: Simplest Way to Check Url for a Parameter and Pass It to Anchor Href If It Exists