Angular 来自 HTTP 调用的动态模板
Angular dynamic template from HTTP call
我有一个简单的问题:在一个简单的 Angular 组件中,我们能否动态更改由 http 调用检索到的模板,例如:
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
/**
* Les liens link permettent de passer d'une page à l'autre.
*/
@Component({
selector: 'mycomponent',
template: '<strong>Loading…</strong>'
})
export class MyComponent implements OnInit {
//#region PROPRIÉTÉS
private moHttp : HttpClient
//#endregion
//#region CONSTRUCTEUR
constructor(poHttp: HttpClient){
this.moHttp = poHttp;
}
public ngOnInit(): void {
this.moHttp.get('https://myapiUrl').subscribe(poData:any => {
// here poData is HTML string, and I want to set it instead of the "<strong>Loading…</strong>"
});
}
}
//#endregion
提前致谢
假设您的 poData
是一个字符串,您可以执行以下操作,
@Component({
selector: 'mycomponent',
template: '<div [innerHTML]="myContent"></div>'
})
export class MyComponent implements OnInit {
private moHttp : HttpClient;
myContent: any= '<strong>Loading…</strong>';
constructor(poHttp: HttpClient, private sanitizer: DomSanitizer){
this.moHttp = poHttp;
}
public ngOnInit(): void {
this.moHttp.get('https://myapiUrl').subscribe(poData:any => {
this.myContent = this.sanitizer..bypassSecurityTrustHtml(poData);
});
}
}
尝试使用
注意:您不必创建新字段来保留注入的服务。
constructor(private http: HttpClient){}
将允许您在 class.
中的任何位置使用 httpClient(如 this.http
)
Angular 本身不支持动态模板。您可以使用延迟加载或直接通过 DOM.
更新视图
...或者有一个非常 hacky hack 来实现它,感谢 DenisVuyka:Full Article
这里我们需要创建NgModule来创建组件工厂,并使用Component装饰器将模板和提供者等元数据传递给组件class。
@Component({
selector: 'runtime-content',
template: `<div #container></div>`
})
export class RuntimeContentComponent {
constructor(public componentRef: ComponentRef, private compiler: Compiler){}
@ViewChild('container', { read: ViewContainerRef })
container: ViewContainerRef;
public compileTemplate(template) {
let metadata = {
selector: `runtime-component-sample`,
template: template
};
let factory = this.createComponentFactorySync(this.compiler, metadata, null);
if (this.componentRef) {
this.componentRef.destroy();
this.componentRef = null;
}
this.componentRef = this.container.createComponent(factory);
}
private createComponentFactorySync(compiler: Compiler, metadata: Component, componentClass: any): ComponentFactory<any> {
const cmpClass = componentClass || class RuntimeComponent { name: string = 'Denys' };
const decoratedCmp = Component(metadata)(cmpClass);
@NgModule({ imports: [CommonModule], declarations: [decoratedCmp] })
class RuntimeComponentModule { }
let module: ModuleWithComponentFactories<any> = compiler.compileModuleAndAllComponentsSync(RuntimeComponentModule);
return module.componentFactories.find(f => f.componentType === decoratedCmp);
}
}
我有一个简单的问题:在一个简单的 Angular 组件中,我们能否动态更改由 http 调用检索到的模板,例如:
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
/**
* Les liens link permettent de passer d'une page à l'autre.
*/
@Component({
selector: 'mycomponent',
template: '<strong>Loading…</strong>'
})
export class MyComponent implements OnInit {
//#region PROPRIÉTÉS
private moHttp : HttpClient
//#endregion
//#region CONSTRUCTEUR
constructor(poHttp: HttpClient){
this.moHttp = poHttp;
}
public ngOnInit(): void {
this.moHttp.get('https://myapiUrl').subscribe(poData:any => {
// here poData is HTML string, and I want to set it instead of the "<strong>Loading…</strong>"
});
}
}
//#endregion
提前致谢
假设您的 poData
是一个字符串,您可以执行以下操作,
@Component({
selector: 'mycomponent',
template: '<div [innerHTML]="myContent"></div>'
})
export class MyComponent implements OnInit {
private moHttp : HttpClient;
myContent: any= '<strong>Loading…</strong>';
constructor(poHttp: HttpClient, private sanitizer: DomSanitizer){
this.moHttp = poHttp;
}
public ngOnInit(): void {
this.moHttp.get('https://myapiUrl').subscribe(poData:any => {
this.myContent = this.sanitizer..bypassSecurityTrustHtml(poData);
});
}
}
尝试使用
注意:您不必创建新字段来保留注入的服务。
constructor(private http: HttpClient){}
将允许您在 class.
this.http
)
Angular 本身不支持动态模板。您可以使用延迟加载或直接通过 DOM.
...或者有一个非常 hacky hack 来实现它,感谢 DenisVuyka:Full Article
这里我们需要创建NgModule来创建组件工厂,并使用Component装饰器将模板和提供者等元数据传递给组件class。
@Component({
selector: 'runtime-content',
template: `<div #container></div>`
})
export class RuntimeContentComponent {
constructor(public componentRef: ComponentRef, private compiler: Compiler){}
@ViewChild('container', { read: ViewContainerRef })
container: ViewContainerRef;
public compileTemplate(template) {
let metadata = {
selector: `runtime-component-sample`,
template: template
};
let factory = this.createComponentFactorySync(this.compiler, metadata, null);
if (this.componentRef) {
this.componentRef.destroy();
this.componentRef = null;
}
this.componentRef = this.container.createComponent(factory);
}
private createComponentFactorySync(compiler: Compiler, metadata: Component, componentClass: any): ComponentFactory<any> {
const cmpClass = componentClass || class RuntimeComponent { name: string = 'Denys' };
const decoratedCmp = Component(metadata)(cmpClass);
@NgModule({ imports: [CommonModule], declarations: [decoratedCmp] })
class RuntimeComponentModule { }
let module: ModuleWithComponentFactories<any> = compiler.compileModuleAndAllComponentsSync(RuntimeComponentModule);
return module.componentFactories.find(f => f.componentType === decoratedCmp);
}
}