【问题标题】:How to create button dynamically with click event in angular 2+如何使用角度 2+ 中的单击事件动态创建按钮
【发布时间】:2019-12-12 05:02:27
【问题描述】:

我想动态创建一个按钮。我使用 innerHtml 来执行此操作。 我可以创建按钮。但它的点击事件不起作用。 请告诉我如何解决这个问题?

这是我的html代码

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

这是我的打字稿代码

 answerPanelContent: any;

   constructor(private sanitizer: DomSanitizer){

   }
ngOnInit() {
 this.answerPanelContent =  this.sanitizer.bypassSecurityTrustHtml(`<button type="button" class="btn                                                    btn-primary float-left"
                                           (click)="removeAnswer()" title="Remove Answer"
                                           aria-label="Close">
                                          Remove</button>`);

  }
    removeAnswer(){
      alert('clicked');
    }

这里是 stackblitz 网址:https://stackblitz.com/edit/angular-nka4w9

【问题讨论】:

  • 这是因为它不会是角度控制的组件,只是说明未消毒的html。
  • 如果我将其指定为未消毒,则按钮不显示
  • 正确的做法是将 HTML 放在模板中,而不是放在 TypeScript 代码中。在模板中的按钮上使用*ngIf="buttonShown",并在TS代码中设置this.buttonShown为true使其出现。
  • @JB Nizet,我做不到,我创建这个问题只知道如何动态执行此操作。实际上我想要的是,我有一个带按钮的输入字段。如果我输入一些东西,点击那个按钮后,我必须用一个按钮显示那个输入值。那个按钮在那个字段必须关闭后点击。这是完整的问题stackoverflow.com/questions/57345041/…
  • 这不会改变任何事情。将 HTML 代码放入模板中,根据组件的状态使用 ngIf 将其移除或添加到页面中。或 ngFor 为数据数组的每个元素生成一行。

标签: angular typescript angular8


【解决方案1】:

我强烈建议不要为此使用[innerHTML]。它不是为此目的,根本不是“角度方式”。

使用 *ngFor

这是解决您的问题的最可取的方式和“角度方式”。

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

使用 Renderer2

仅当*ngFor 由于某些我们不知道的要求而无法解决您的问题时才使用此选项。

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>

这是一个工作的StackBlitz

【讨论】:

  • 为什么要这样?为什么不直接将 HTML 放入模板中,然后使用 ngFor?
  • 也可以添加 - 他在评论中说这对他不起作用。可能是一个特定的要求或阻止他使用它的东西。
  • 我明白了。但不是。只是他/她不了解 Angular 的原理。一个使用 ngFor 的基本 stackblitz 示例最终让他/她意识到它运行良好,当然。见stackoverflow.com/questions/57345596/…
  • @pascalpuets,这种方式也有效。非常感谢您的帮助。你能检查一下这个问题吗stackoverflow.com/questions/57239513/…
  • @JBNizet 似乎我错过了那条评论。当然*ngFor 是解决这个问题的最佳方式。也是 Angular 开发人员应该知道的最基本的事情之一。
猜你喜欢
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 2014-02-23
  • 2017-10-14
  • 2011-05-01
  • 1970-01-01
  • 2019-08-04
相关资源
最近更新 更多