来自 HTTP 调用的 Angular 动态模板

标签 angular http angular2-template

我有一个简单的问题:在一个简单的 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

提前致谢

最佳答案

Angular 本身不支持动态模板。您可以使用延迟加载或直接通过 DOM 更新 View 。

... 或者有一个非常 hacky hack 来实现它,感谢 DenisVuyka:Full Article

这里我们需要创建 NgModule 来创建组件工厂,并使用组件装饰器将模板和提供者等元数据传递给组件类。

@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);
    }
}

关于来自 HTTP 调用的 Angular 动态模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51891236/

相关文章:

angular - 在 Angular 6 中设置文件输入的值

python - 使用 GIO 的异步 HTTP 请求

http - 结合 websockets 和 http

angular - 如果其他选择框选项更改为 Angular 2.0 中的相同选项,如何添加和删除选择框选项

angular - 从组件类访问模板引用变量

javascript - 访问组件内部的模板变量

netbeans - 将 Angular2 指令添加到 Netbeans IDE

css - Angular Material 自定义徽章尺寸

node.js - Ubuntu 15.10 服务器上的 NodeJS http 服务器 : New Install : ERR_CONNECTION_REFUSED externally

angular - 自动将子组件数据更改发送到父组件