Compile dynamic HTML in Angular 4/5- something similar to $compile in Angular JS

前端 未结 4 1399
夕颜
夕颜 2020-11-27 16:54

I wanted to receive an HTML data via service call to server(this is for sure. I cannot keep templates in local) and manipulate them internally on how to show it(either as a

4条回答
  •  北海茫月
    2020-11-27 17:16

    For rendering HTML on the fly, you need DomSanitizer. E.g. something like this:

    
    
    // component import { Component } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; @Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: [ './app.component.css' ] }) export class AppComponent { htmlData: any; constructor(private sanitizer: DomSanitizer) {} ngOnInit() { this.htmlData= this.sanitizer.bypassSecurityTrustHtml('

    Safe Html

    Server prepared this html block.
    '); } }

    Now, that's the gist of it. You obviously also need a loading mechanic. You might also want to include some data into this block - if it's simple data, it can be on the fly:

    this.htmlData = this.sanitizer.bypassSecurityTrustHtml(`
    ${this.someValue}
    `);

    For more complex scenarios you might need to create a dynamic component.

    Edit: an example of a component resolved dynamically. With this, you create a component on-the-fly from server-sent html.

    @Component({
      selector: 'my-component',
      template: `

    Stuff bellow will get dynamically created and injected

    ` }) export class TaggedDescComponent { @ViewChild('vc', {read: ViewContainerRef}) vc: ViewContainerRef; private cmpRef: ComponentRef; constructor(private compiler: Compiler, private injector: Injector, private moduleRef: NgModuleRef, private backendService: backendService, ) {} ngAfterViewInit() { // Here, get your HTML from backend. this.backendService.getHTMLFromServer() .subscribe(rawHTML => this.createComponentFromRaw(rawHTML)); } // Here we create the component. private createComponentFromRaw(template: string) { // Let's say your template looks like `

    ` // As you see, it has an (existing) angular component `some-component` and it injects it [data] // Now we create a new component. It has that template, and we can even give it data. const tmpCmp = Component({ template, styles })(class { // the class is anonymous. But it's a quite regular angular class. You could add @Inputs, // @Outputs, inject stuff etc. data: { some: 'data'}; ngOnInit() { /* do stuff here in the dynamic component */} }); // Now, also create a dynamic module. const tmpModule = NgModule({ imports: [RouterModule], declarations: [tmpCmp], // providers: [] - e.g. if your dynamic component needs any service, provide it here. })(class {}); // Now compile this module and component, and inject it into that #vc in your current component template. this.compiler.compileModuleAndAllComponentsAsync(tmpModule) .then((factories) => { const f = factories.componentFactories[0]; this.cmpRef = f.create(this.injector, [], null, this.moduleRef); this.cmpRef.instance.name = 'my-dynamic-component'; this.vc.insert(this.cmpRef.hostView); }); } // Cleanup properly. You can add more cleanup-related stuff here. ngOnDestroy() { if(this.cmpRef) { this.cmpRef.destroy(); } } }

提交回复
热议问题