【问题标题】:How can I load a HTML template from file during runtime?如何在运行时从文件中加载 HTML 模板?
【发布时间】:2019-12-19 04:36:00
【问题描述】:

我正在尝试将 HTML 模板动态加载到 Angular 8 应用程序中的组件。不幸的是,我的解决方案似乎不适用于 build --prod Sop 我该怎么办?

在我的项目中,我尝试创建一个动态组件,该组件在应用程序运行时加载其 HTML 模板。所以我搜索了很多,并在下面找到了这个解决方案(有点简化)。它在开发环境中运行良好,但不适用于生产环境。

import {
    Compiler, Component, Injector, VERSION, Input, ViewChild, NgModule, NgModuleRef,
ViewContainerRef, AfterViewInit, OnInit, ComponentFactoryResolver
} from '@angular/core';
import { BrowserModule }    from '@angular/platform-browser';


@Component({
    selector: 'dyn-component',
    template: `<ng-container #dynamicTemplate></ng-container>`
})
export class DynComponent implements AfterViewInit, OnInit {
    @ViewChild('dynamicTemplate', {static: true, read: ViewContainerRef}) dynamicTemplate;
    @Input() data:any;

constructor(
    private _compiler: Compiler,
    private _injector: Injector,
    private _m: NgModuleRef<any>,
    private componentFactoryResolver: ComponentFactoryResolver,
    public viewContainerRef: ViewContainerRef
) 
{}


ngOnInit() {
}

ngAfterViewInit() {
    let myTemplateUrl = '/assets/scoreboard/BER/template.html';

    const tmpCmp = Component({
        moduleId: module.id, templateUrl: myTemplateUrl
    })
    (
        class {}
    );


    const tmpModule = NgModule({
        imports: [BrowserModule],
        declarations: [tmpCmp]})(class {
    });

    this._compiler.compileModuleAndAllComponentsAsync(tmpModule)
                  .then((factories) => {
                        const f = factories.componentFactories[0];
                        const cmpRef = f.create(this._injector, [], null, this._m);
                        cmpRef.instance.name = 'dynamic';
                        cmpRef.instance.data = this.data;

                        this.dynamicTemplate.insert(cmpRef.hostView);
                  });
}

那么,如何创建一个动态组件,其中模板 URL 作为参数给出,然后在运行时创建该组件?或者:如何替换组件中已经加载的模板?

请问,谁能帮我解决这个问题?

【问题讨论】:

  • 原因是 Angular AOT 之前预编译了组件。但是您可以动态加载组件,但 Angular 仍然需要在 entryComponents angular.io/guide/dynamic-component-loader 中了解它们
  • @SGalea 这是我在阅读文档时所理解的。问题是我只有ca。 25 个使用相同数据但 HTML 不同的组件。这就是为什么我正在寻找一种只有一个组件但带有外部加载模板的方法。

标签: angular templates dynamic components


【解决方案1】:

只是为了给你一个不强迫你在这里创建 25 个组件的答案,这是一种简单的处理方法。由于您已准备好动态注入模板,因此我假设您的组件 JavaScript 在组件之间不会有太大差异,否则无论哪种方式都达不到目的。

import { Component, Input } from '@angular/core';

@Component({
  selector: 'hello',
  template: `
<div *ngIf='template == "template1"'>
  <div class="companyLogo">
    <img [src]="logoSourceUrl">
    <label>First Template</label>
  </div>
</div>

<div *ngIf='template == "template2"'>
  <div class="companyLogo">
    <img [src]="logoSourceUrl">
    <label>Second Template</label>
  </div>
</div>
  `,
  styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent  {
  @Input() template: string;
}

用法:

<hello template="template1"></hello>
<hello template="template2"></hello>

Demo 这个。

【讨论】:

  • 同时我写了类似的东西 :-) 但是谢谢你的帮助。对我来说,这是 Angular 架构中真正缺乏或缺失的功能,因为模板通常来自数据库。好吧,也许在 v9 中:-)
  • 我知道你的意思,我同意,但我非常怀疑你很快就会在 Angular 中看到这一点。我们在 Angular 2 中失去了这个功能
猜你喜欢
  • 1970-01-01
  • 2021-07-02
  • 1970-01-01
  • 2012-09-13
  • 1970-01-01
  • 2013-08-27
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
相关资源
最近更新 更多