I have load the HTML
page by http.get()
method, and i add content this page to div tag.
getRequestToAssignPage (param: string) : an
In your template, you can set up something like:
<div #htmlContainer [innerHTML]="trustedHTML"></div>
In the corresponding component, you can load your HTML into your template, build up an array of script tags, and eval
each one:
@ViewChild('htmlContainer') container;
ngOnInit() {
this.http.get('html-file.html').subscribe((res: Response) => {
this.trustedHTML = this.sanitizer.bypassSecurityTrustHtml(res.text());
setTimeout(() => { //wait for DOM rendering
let scripts = this.container.nativeElement.getElementsByTagName('script');
for (let script of scripts){
eval(script.text)
}
})
});
I hate that I have to resort to using setTimeout
and eval
for something so seemingly simple, but it works.
...but not for <script src="...
. I ended up importing jQuery and using $(parent).load(url);. If someone has a pure Angular solution, please post it.
Based on the Adam's solution you can implement a custom directive along with the pipe and re-insert scripts into the DOM. This would account for both cases: inline scripts and "src" scripts. Keep in mind that allowing scripts like so is very dangerous.
Pipe:
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({ name: 'safeHtml' })
export class SafeHtmlPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) { }
transform(html) {
return this.sanitizer.bypassSecurityTrustHtml(html);
}
}
Directive:
import { Directive, ElementRef, OnInit } from '@angular/core';
@Directive({ selector: '[runScripts]' })
export class RunScriptsDirective implements OnInit {
constructor(private elementRef: ElementRef) { }
ngOnInit(): void {
setTimeout(() => { // wait for DOM rendering
this.reinsertScripts();
});
}
reinsertScripts(): void {
const scripts = <HTMLScriptElement[]>this.elementRef.nativeElement.getElementsByTagName('script');
const scriptsInitialLength = scripts.length;
for (let i = 0; i < scriptsInitialLength; i++) {
const script = scripts[i];
const scriptCopy = <HTMLScriptElement>document.createElement('script');
scriptCopy.type = script.type ? script.type : 'text/javascript';
if (script.innerHTML) {
scriptCopy.innerHTML = script.innerHTML;
} else if (script.src) {
scriptCopy.src = script.src;
}
scriptCopy.async = false;
script.parentNode.replaceChild(scriptCopy, script);
}
}
}
Usage:
<div [innerHTML]="myDynamicMarkup | safeHtml" runScripts></div>