简体   繁体   中英

Call component function from dom generated element - angular

I want to create a dynamic number of html dom element buttons and have them be able to call a service when clicked. Is there any way to do that?

For example, test.component.ts:

import {ApiService } from '../services/api.service';
...
export class test implement OnInit(){
    constructor(private apiGet : ApiService) { }
    ngOnInit() {
        ...
        for (i = 0; i < x; i++) {
            var row = document.getElementById('row');
            var cell = insertCell();
            cell.innerHTML = "<button name='" + i + '" (click)=test.callService()>click me</button>";
        }
    }
    public callService() {
        //call ApiService here using buttons name
    }
}

I've been getting it to work when I put the (click) event on an html element inside test.component.html, but it hasn't been working for the dom generated buttons. Is there something I'm missing, or is there a better way to do this?

For dynamically created elements, event handlers have to be defined using addEventListener() method. Also you could manually trigger change detection to make sure the elements are generated in DOM. Try the following

import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { ApiService } from '../services/api.service';
...
export class test implement OnInit {
  constructor(private apiGet: ApiService, private _cdr: ChangeDetectorRef) { }

  ngOnInit() {
    ...
    for (i = 0; i < x; i++) {
      var row = document.getElementById('row');
      var cell = insertCell();
      cell.innerHTML = "<button id='button" + i + "' name='" + i + '">click me</button>";
    }
    this.addEventListeners(x);
  }

  private addEventListeners(x) {
    this._cdr.detectChanges();    // <-- manually trigger change detection to be sure
    for (i = 0; i < x; i++) {
      const button = document.getElementById('button' + i);
      if (button) {
        button.addEventListener('click', this.callService());
      }
    }
  }

  public callService() {
      //call ApiService here using buttons name
  }
}

Also unrelated, export class test implement OnInit(){ should be replaced with export class test implement OnInit { . The parentheses are not required here.

Your html using ngFor

 <div *ngFor="let button of buttons">
     <button (click)="callService(button.name)">{{button.name}}</button>
 </div>

And your component:

  buttons = [
    {
      name: 'one'
    },
    {
      name: 'two'
    }
  ];

  callService(buttonName) {
    alert(`call ApiService here using buttons name: [${buttonName}]`);
  }

Check this stackblitz .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM