Estoy trabajando en una plantilla dinámica de generación usando angular 6. Tengo una API que devuelve cadenas como a continuación:

    <button type="button" (click)="openAlert()">click me</button>

Y html

    <div [innerHtml]="myTemplate | safeHtml">
      </div>

La función está abajo:

    openAlert() {
        alert('hello');
      }
1
Abhijit Patil 31 oct. 2019 a las 13:43

3 respuestas

La mejor respuesta

No puede vincular eventos angulares directamente a innerHTML.

Aún así, si necesita adjuntar los oyentes de eventos, debe hacerlo después de cargar el contenido html.

Una vez que el contenido se establece en la variable, se activará el evento ngAfterViewChecked Angular life cycle. Aquí debe adjuntar los oyentes de eventos necesarios.

Vea el ejemplo de trabajo a continuación.

Componente.html

<button (click)="addTemplate()">Get Template</button>
<div [innerHTML]="myTemplate | safeHtml"></div>

Component.ts

import { Component, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  myTemplate  = '';

  constructor(private elementRef:ElementRef){

  }
  openAlert() {
    alert('hello');
  }
  addTemplate(){
     this.myTemplate  = '<button type="button" id="my-button" (click)="openAlert()">click mee</buttn>';
  }
  ngAfterViewChecked (){
    if(this.elementRef.nativeElement.querySelector('#my-button')){
      this.elementRef.nativeElement.querySelector('#my-button').addEventListener('click', this.openAlert.bind(this));
    }
  } 
}

Safe-html.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({
  name: 'safeHtml'
})
export class SafeHtmlPipe implements PipeTransform {
constructor(private sanitized: DomSanitizer) {}
  transform(value) {
        return this.sanitized.bypassSecurityTrustHtml(value);
    }

}
0
Narayanan 31 oct. 2019 a las 11:16

Básicamente esto no funcionará. Cuando escribe código en Angular, es transpiled por webpack y convertido a JavaScript que se ejecuta en el navegador.

Sin embargo, ahora está inyectando Angular code dinámicamente y no build. La detección de eventos (click) no funcionaría de forma nativa y la función openAlert tampoco está en el ámbito global donde se inyecta. Tendrá que considerar un enfoque diferente y generar contenido utilizando <ng-template> según la respuesta de API.

0
Dhananjai Pai 31 oct. 2019 a las 10:54

Esto también debería funcionar:

Componente.html

<div #template></div>

Component.ts

@ViewChild('template') myTemplate: ElementRef;

addTemplate(){
   this.myTemplate.nativeElement.innerHTML = '<button type="button">click me</button>';
   this.myTemplate.nativeElement.addEventListener('click', this.openAlert);
}
0
crazy_p 31 oct. 2019 a las 11:39