typescript Angular 4 在按钮上动态添加点击事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47669161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:05:45  来源:igfitidea点击:

Angular 4 add click event on button dynamically

angulartypescript

提问by Tarun Mishra

Here is the code of button displayed from loop.

这是循环显示的按钮代码。

for( let k=0; k<this.newTmpArr.length; k++ ){
    myTable += "<tr>";            
    for( let key2 in this.newTmpArr[k] ){
        if(this.newTmpArr[k][key2] == 'button' ){
          myTable += `<td><button (click)="test()">Click</button></td>`; 
          break;    
        }
        if(this.newTmpArr[k][key2] == 'link' ){
          myTable += `<td><a href="#" (click)="test()">Click</a></td>`; 
          break;    
        } else {
          myTable += "<td>" + this.newTmpArr[k][key2] + "</td>";                    
        }

    }
    myTable += "</tr>"; 
}

test(){
  alert("Working!");
}

Here is the screenshot of the page look like after dynamic data rendered.

这是动态数据呈现后的页面截图。

enter image description here

在此处输入图片说明

回答by Pranay Rana

Read for detail : Dynamic Html Structure with - *ngIf, *ngFor & ngSwitch

阅读详细信息:带有 - *ngIf、*ngFor 和 ngSwitch 的动态 Html 结构

you can try out , Template way below is working fine without much change, below took just 20 min

你可以试试,下面的模板方式工作正常,没有太大变化,下面只用了 20 分钟

App.Component.html --- template file

App.Component.html --- 模板文件

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>Date</th>
      <th>Ammount</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
   <tr *ngFor="let ele of newTmpArr" >
     <td>{{ele[0]}}</td>
     <td>{{ele[1]}}</td>
     <td>{{ele[2]}}</td>
     <td>
        <div ngSwitch="{{ele[3]}}">
            <div *ngSwitchCase="'button'">
              <input type="button" (click)="DoWork(1)" value="click"/>
            </div>
            <div *ngSwitchCase="'link'">
                <a href="#" (click)="DoWork(1)" >click</a>
            </div>
        </div> 
     </td>
   </tr>
  </tbody> 
</table>

App.Component.ts--typescript

App.Component.ts--打字稿

export class AppComponent implements OnInit {
ngOnInit(): void {}
title = 'app';
DoWork()
  {
    //here you can do work , 
    //this get called when you press "click" button in table 
    alert(this.title);
  }
}


Without template dynamic way

无模板动态方式

It took me 5 hours to reach this code but fater that Following is working fine , you need to by pass security with the help of DomSanitizeras you want to put input element from you template file.

我花了 5 个小时才到达此代码,但由于以下工作正常,您需要在DomSanitizer要从模板文件中放置输入元素时绕过安全性。

//typings.d.ts
interface Window { my: any; }

above one extends your window object

上面的一个扩展了您的窗口对象

app.Component.html

应用程序组件.html

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>Date</th>
      <th>Ammount</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody id="tid" [innerHTML]="bodytext"></tbody> 
</table>

typescript file - app.Component.ts

打字稿文件 - app.Component.ts

import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import {Component, NgZone, OnInit, OnDestroy} from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})

export class AppComponent implements OnInit {
   title = 'app';
  _myTable : string;
  bodytext ;
  newTmpArr = [
          ["567", "2017-04-17T14:22:48", "45000", "button"],
          ["567", "2017-04-17T14:22:48", "45000", "button"],
          ["567", "2017-04-17T14:22:48", "45000", "link"],
          ["567", "2017-04-17T14:22:48", "45000", "button"]
        ];
   constructor(private http: Http,private _sanitizer: 
                 DomSanitizer,private ngZone: NgZone) {
   }

  ngOnInit(): void {
    //below code add dynamci table to your html
    for( let k=0; k<this.newTmpArr.length; k++ ){
            this._myTable += "<tr>";            
            for( let key2 in this.newTmpArr[k] ){
                if(this.newTmpArr[k][key2] == 'button' ){
                //below is table click button calls angular function, 
                //here 1 is passed as arugment you can pass 
                //any other value you want
                //or if you dont want to pass than just do
                // onclick="my.namespace.publicFunc();" 
                // and remove parameter from typscript function also 
                this._myTable += `<td><input  type="button" 
                   onclick="my.namespace.publicFunc(1);" 
                   value="Click me"  /></td>`; 
                break;    
                }
                if(this.newTmpArr[k][key2] == 'link' ){
                this._myTable += `<td><a href="#"
                        onclick="my.namespace.publicFunc(1); 
                             return false;">Click</a>
                         </td>`; 
                break;    
                } else {
                this._myTable += "<td>" + 
                   this.newTmpArr[k][key2] + "</td>";                    
                }
            }
            this._myTable += "</tr>"; 
        }
         this.bodytext = 
        this._sanitizer.bypassSecurityTrustHtml(this._myTable);
        //code to add dynamic html ends here 

         //below script helps to expose anglar function to javascript 
         window.my = window.my || {};
         window.my.namespace = window.my.namespace || {};
        //below line bind typescript function to window object publicFunc
         window.my.namespace.publicFunc = 
          this.OnTableButtonClick.bind(this);
        //code to expose typscipt function ends here 
  }

  //this function get called when Table click button ge clicked 
  public OnTableButtonClick(input:string):void{ 
    this.ngZone.run(() => this.DoWork(input)); 
  }

  DoWork(input:string)
  {
    //here you can do work , 
    //this get called when you press "click" button in table 
    alert(this.title + input);
    //this will display app1 in output
  }
}

回答by bryan60

I'm going to go ahead and post the way I feel this should be done, in the angular way. Writing html in code almost always means you're doing something wrong. This is template logic that should be done IN TEMPLATE, like this:

我将继续以有角度的方式发布我认为应该完成的方式。在代码中编写 html 几乎总是意味着你做错了什么。这是应该在模板中完成的模板逻辑,如下所示:

<tr *ngFor="let row of newTmpArr">
  <td *ngFor="let cell of row">
    <ng-container [ngSwitch]="cell">
      <button *ngSwitchCase="'button'" (click)="test()">Click</button>
      <a *ngSwitchCase="'link'" href="#" (click)="test()">Click</a>
      <ng-container *ngSwitchDefault>{{ cell }}</ng-container>
    </ng-container>
  </td>
</tr>

This is the angular way of achieving your goal, all done in template, using nested ng for loops and then an ngSwitch is the appropriate directive for this use case since you have 2 options and a default. Now you do not need to fight the framework or use any hacks like binding functions to the window. Angular will bind functions appropriately using this method. You also have the distinct advantage of your display being model driven, so you only need to ever update your model and the display will react accordingly, so you never need to worry about display and model falling out of sync.

这是实现目标的角度方式,全部在模板中完成,使用嵌套的 ng for 循环,然后 ngSwitch 是适合此用例的指令,因为您有 2 个选项和一个默认值。现在您不需要与框架作斗争或使用任何技巧,例如将函数绑定到窗口。Angular 将使用此方法适当地绑定函数。您还拥有显示器由模型驱动的独特优势,因此您只需要更新您的模型,显示器就会做出相应的反应,因此您无需担心显示器和模型不同步。

For example if you were to remove row 5, you would need to manually redraw your table after updating your model, same if you added a new row, or if you edit cell 2 of row 3. Using template, angular manages all of this in a transparent and reliable manner.

例如,如果您要删除第 5 行,则需要在更新模型后手动重绘表格,如果添加新行或编辑第 3 行的单元格 2,则同样如此。使用模板,angular 管理所有这些一种透明和可靠的方式。

回答by Tarun Mishra

here is the code work for me. it may helpful for you guys too.

这是对我有用的代码。它可能对你们也有帮助。

<tr *ngFor="let item of newTmpArr">
       <td *ngFor="let i of item">
          <span *ngIf="i.value; then dynamicVal; else elseblock"></span>
          <ng-template #dynamicVal>
          <span *ngIf="i.type == 'button'">
          <button (click)="clickMe(item)">Click</button>
          </span>
          <span *ngIf="i.type == 'link'">
             <a [href]="i.link">{{i.value}}</a>
          </span>
          </ng-template> 
          <ng-template #elseblock>{{i}}</ng-template>
       </td>
</tr> 

回答by Neji

As said above you can use the *ngFor in your table row in your component.html file. Then in the button tag handle the click event as you would normally do.

如上所述,您可以在 component.html 文件的表格行中使用 *ngFor。然后在按钮标签中像往常一样处理点击事件。

<td> <button (click)="clickEvent()"> Click </button> </td>

Then in your component.ts file define the on click event

然后在你的 component.ts 文件中定义点击事件

clickEvent(){console.log("click event triggered")}