在 Angular 4/5 中编译动态 HTML - 类似于 Angular JS 中的 $compile [英] Compile dynamic HTML in Angular 4/5- something similar to $compile in Angular JS
问题描述
我想通过对服务器的服务调用接收 HTML 数据(这是肯定的.我不能将模板保存在本地)并在内部操作它们以了解如何显示它(作为模态页面或整页).这个带有 Angular 标签的 HTML 应该循环到一个组件中并一起工作.在 Angular JS 中最多只有一种 $compile.
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 modal or full page). This HTML with Angular tags should be looped to a component and work together. At most kind of $compile in Angular JS.
我正在 Angular 5 中开发解决方案,应该与 AOT 编译器兼容.我提到了几个解决方案,但对已弃用和更新的解决方案感到困惑.请帮我.我相信您更新后的答案也会对其他人有所帮助.. 在此先感谢您!
I am developing the solution in Angular 5 and should be compatible with AOT compiler. I had referred several solutions and landed to confusion on the deprecated and updated solutions. Please help me. I believe your updated answer would help many other people as well.. Thank you so much in advance!
推荐答案
为了动态呈现 HTML,您需要 DomSanitizer.例如.像这样:
For rendering HTML on the fly, you need DomSanitizer. E.g. something like this:
<!-- 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>');
}
}
现在,这就是它的要点.你显然还需要一个加载机制.您可能还想在此块中包含一些数据 - 如果它是简单数据,则可以是动态的:
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(`<div>${this.someValue}</div>`);
对于更复杂的场景,您可能需要创建一个动态组件.
For more complex scenarios you might need to create a dynamic component.
一个动态解析的组件示例.有了这个,您可以从服务器发送的 html 即时创建一个组件.
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: `<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();
}
}
}
这篇关于在 Angular 4/5 中编译动态 HTML - 类似于 Angular JS 中的 $compile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!