如何在运行时从文件中加载 HTML 模板?

Posted

技术标签:

【中文标题】如何在运行时从文件中加载 HTML 模板?【英文标题】:How can I load a HTML template from file during runtime? 【发布时间】: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 不同的组件。这就是为什么我正在寻找一种只有一个组件但带有外部加载模板的方法。 【参考方案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 中失去了这个功能

以上是关于如何在运行时从文件中加载 HTML 模板?的主要内容,如果未能解决你的问题,请参考以下文章

如何在html文件中加载css文件已经在django中扩展了另一个html文件(base.html)

如何在页面加载时从表中加载一定数量的行,并且仅在用户加载它们时才加载更多行?

如何在 webpack 中加载 Pug 模板而不编译为 HTML?

在Vue中加载页面时从列表中调用json

如何在 Keycloak .ftl 模板中加载用户数据?

在 H2 中初始化数据时从文件中加载数据