Update 2
If you do not want to make use of library, you can use the class Compiler ( Note: Not to be confused with $compile
of Angularjs )
Filing cabinet app.componentts.
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);
})
}
}
Filing cabinet app.component.html
<div #testando></div>
See working in stackblitz
The above example 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
Doing a search on Google, found the library p3x-angular-Compile.
To use, just follow the steps:
Import library into archive app.modulets.
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 like this in the question, with the exception that events should 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 in stackblitz
This is not possible, because the subclass DomSanitizer
simply ignores, the solution would be to use the method addEventListener
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 in stackblitz