我希望通过服务调用服务器接收HTML数据(这是肯定的.我不能在本地保存模板)并在内部操作它们如何显示它(作为模态或整页).带有Angular标记的HTML应该循环到一个组件并一起工作.在Angular JS中大多数是$compile.
我正在开发Angular 5中的解决方案,并且应该与AOT编译器兼容.我已经提到了几个解决方案,并且对已弃用和更新的解决方案感到困惑.请帮帮我.我相信你的最新答案也可以帮助很多其他人..非常感谢你提前!
要动态呈现HTML,您需要DomSanitizer.例如.像这样的东西:
<!-- template --> <div [innerHTML]="htmlData"></div> // 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('<div style="border: 1px solid red;"><h2>Safe Html</h2><span class="user-content">Server prepared this html block.</span></div>'); } }
现在,这就是它的要点.你显然还需要一个加载机制.您可能还希望在此块中包含一些数据 – 如果它是简单数据,则可以在运行中:
this.htmlData = this.sanitizer.bypassSecurityTrustHtml(`<div>${this.someValue}</div>`);
对于更复杂的方案,您可能需要创建动态组件.
编辑:动态解析的组件示例.有了这个,您可以从服务器发送的html中即时创建一个组件.
@Component({ selector: 'my-component',template: `<h2>Stuff bellow will get dynamically created and injected<h2> <div #vc></div>` }) export class TaggedDescComponent { @ViewChild('vc',{read: ViewContainerRef}) vc: ViewContainerRef; private cmpRef: ComponentRef<any>; constructor(private compiler: Compiler,private injector: Injector,private moduleRef: NgModuleRef<any>,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 `<h2><some-component [data]="data"></some-component>` // 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(); } } }