0

I bind html via innerHtml in Angular:

test = 'abc';

constructor(private elementRef: ElementRef, private sanitizer: DomSanitizer) {
    this.content = this.sanitizer.bypassSecurityTrustHtml(
      '<button type="button" id="submitButton" (click)="openWindow()">{{test}} Submit</buttn>'
    );
}

openWindow() {
    alert('Welcome2');
}

https://stackblitz.com/edit/angular-innerhtml-examples-hjgnzq

Of course "abc" isn't rendered. Is it possible to run angular code inside the innerHtml attribute?

daniel
  • 34,281
  • 39
  • 104
  • 158

1 Answers1

1

You need a mix of the two response to this SO

It's like this SO

First you need take account that Angular not "compile at time". But "get" a button or an href is easy thanks the directive of @k-coding

Well, we can transform a bit the directive to get the attribute (click) an know the function and the possibles arguments

export class CustomLinkDirective {
  @Input()
  appStyle: boolean = true;
  constructor(private ref: ElementRef ) {}

  @HostListener("click", ["$event"])
  onClick(e: any) {
    e.preventDefault();
    const href = e.target.getAttribute("(click)");
    if (href)
    {
      const arg=href.match(/\((.+)\)/)
      const funcion=(arg==null)?href.replace('()',''):href.replace(arg[0],'')
      this.ref.nativeElement.dispatchEvent(
        new CustomEvent<any>('doit', { detail: {function:funcion,arg:arg?arg[1]:null }})
      )
    }
  }
}

Your .html becomes like (I added a template reference variable

<span #span linkify [innerHtml]="content"></span>

And your code like

  @ViewChild('span',{read:ElementRef,static:true}) span!:ElementRef

  subscripton:any
  constructor(private elementRef: ElementRef, private sanitizer: DomSanitizer) {
    this.content = this.sanitizer.bypassSecurityTrustHtml(
      `<button type="button" id="submitButton" (click)="openWindow(1)">${this.test} Submit</button><br/>
      <button type="button" id="submitButton" (click)="openWindow(hello)">${this.test} Submit</button><br/>`
    );
  }
  ngOnInit(){
    this.subscripton=fromEvent(this.span.nativeElement,'doit').subscribe((res:any)=>{
      this[res.detail.function](res.detail.arg)
      
   })
  }
  ngOnDestroy()
  {
    this.subscripton.unsubscribe()
  }
  openWindow(arg:any=null) {
    alert('Welcome '+(arg?arg:''));
  }

See stackblitz

Update really is better an more Angular aproach

We can add an output to our directive

@Output('linkify') executeAction=new EventEmitter<any>()

And when click

if (href)
{
  const arg=href.match(/\((.+)\)/)
  const funcion=(arg==null)?href.replace('()',''):href.replace(arg[0],'')
  this.executeAction.emit({function:funcion,arg:arg?arg[1]:null })
}

So, our .html like

<span #span (linkify)="executeAction($event)" 
    [innerHtml]="content"></span>

And our function

  executeAction(event)
  {
    this[event.function](event.arg)
  }
Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • NOTE: I reopened the question. Please if someone close a question indicating is a question repeated be sure: 1.-really is repeated, 2.-is resolved the question – Eliseo Mar 15 '22 at 10:53