Update 2
If you do not want to use the library, you can use the class Compiler (Note: Do not confuse with $compile
of AngularJS )
Archive app.component.ts
import { Compiler, Component, Injector, NgModule, NgModuleRef, ViewChild, ViewContainerRef } from "@angular/core";
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
@ViewChild('testando', { read: ViewContainerRef }) _container: ViewContainerRef;
constructor(private _compiler: Compiler, private _injector: Injector, private _m: NgModuleRef<any>) { }
test() {
alert('Teste :D');
}
ngAfterViewInit() {
const html_string = '<input type="button" (click)="test()" value={{btnValue}}>';
const tmpCmp = Component({ template: html_string })(class { });
const tmpModule = NgModule({ declarations: [tmpCmp] })(class { });
this._compiler.compileModuleAndAllComponentsAsync(tmpModule)
.then((factories) => {
const f = factories.componentFactories[0];
const cmpRef = f.create(this._injector, [], null, this._m);
cmpRef.instance.btnValue = 'CLIQUE!';
cmpRef.instance.test = this.test;
this._container.insert(cmpRef.hostView);
})
}
}
Archive app.component.html
<div #testando></div>
See working at stackblitz
The example above was adapted from the article: Here is what you need to know about dynamic components in Angular . (Here's what you need to know about dynamic components in Angular - Free translation.)
Update 1
By doing a search on Google , I found the p3x-angular-compile library.
To use, just follow the steps below:
Import the library into the app.module.ts
import { CompileModule} from 'p3x-angular-compile';
Configure the module:
@NgModule({
imports: [ ... CompileModule],
...
})
Template Code:
<div *ngIf="true"
[p3x-compile]="html_string"
[p3x-compile-ctx]="this" >
</div>
Use your component normally just like this in the question, with the exception that events must be preceded by context.
:
html_string = '<input type="button" (click)="context.test('wmsouza')" value="CLIQUE AQUI!">';
test(nome) {
alert('Olá, ${nome}');
}
You can see it working at stackblitz
This is not possible since the subclass DomSanitizer
simply ignores, the solution would be to use the addEventListener
method to register an event in the element.
import { Component, ChangeDetectorRef, ElementRef } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
html_string;
constructor(private sanitizer: DomSanitizer, private elRef: ElementRef, private cdRef: ChangeDetectorRef) { }
test = (nome) => {
alert('Olá, ${nome}');
}
ngOnInit() {
this.html_string = this.sanitizer.bypassSecurityTrustHtml('<input type="button" value="CLIQUE AQUI!">');
this.cdRef.detectChanges();
this.elRef.nativeElement.querySelector('input').addEventListener('click', _ => { this.test('wmsouza') }, false);
}
}
See working at stackblitz