You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular表单构建:如何在ng-container中用对象属性作为templateRef?

问题:Angular中通过配置动态指定ngTemplateOutlet模板报错

错误信息

ERROR TypeError: templateRef.createEmbeddedViewImpl is not a function
    at ViewContainerRef.createEmbeddedView (core.mjs:19896:37)
    at NgTemplateOutlet.ngOnChanges (common.mjs:3951:46)
    at NgTemplateOutlet.rememberChangeHistoryAndInvokeOnChangesHook (core.mjs:2514:14)
    at callHookInternal (core.mjs:3524:14)
    at callHook (core.mjs:3555:9)
    at callHooks (core.mjs:3506:17)
    at executeInitAndCheckHooks (core.mjs:3456:9)
    at selectIndexInternal (core.mjs:11954:17)
    at Module.ɵɵadvance (core.mjs:11937:5)
    at ModalComponent_ng_template_3_Template (modal.component.html:16:20)
handleError @ core.mjs:11752

相关代码

form-build.html

<ng-template #input let-item="item">
    <mat-form-field class="example-form-field">
        <mat-label>Clearable input</mat-label>
        <input matInput type="text">
        <mat-icon matSuffix svgIcon="heroicons_outline:user-circle"></mat-icon>
    </mat-form-field>
</ng-template>

<ng-container *ngTemplateOutlet="template; context: { formConfig: formConfig }"></ng-container>

<ng-template #template let-config="formConfig">
    <!-- 报错的容器 -->
    <ng-container [ngTemplateOutlet]="config['perguntaForm'].formFieldType" [ngTemplateOutletContext]="{item: config['perguntaForm']}"></ng-container>
    <!-- 正常渲染的容器 -->
    <ng-container [ngTemplateOutlet]="input" [ngTemplateOutletContext]="{item: config['perguntaForm']}"></ng-container>
</ng-template>

form-build.ts

@Component({
...})
export class FormConfig {
  formConfig: any = {
    perguntaForm: {
      formFieldType:'input',
      type: 'text'
    },
  }
}

尝试强制声明类型也无效:

@Component({
...})
export class FormConfig {
  formConfig: any = {
    perguntaForm: {
      formFieldType:TemplateRef<'input'>,
      type: 'text'
    },
  }
}

问题原因

ngTemplateOutlet要求绑定的是TemplateRef实例,但你在formConfig里给的formFieldType是字符串'input',Angular无法将字符串识别为模板引用,因此抛出createEmbeddedViewImpl is not a function错误。强制声明类型只是TypeScript层面的类型断言,实际值还是字符串,无法解决问题。

解决方案

需要将字符串标识和对应的TemplateRef实例做映射,具体步骤如下:

  1. 在组件中通过ViewChild获取模板引用并建立映射:
import { Component, ViewChild, TemplateRef, AfterViewInit } from '@angular/core';

@Component({
  ...
})
export class FormConfig implements AfterViewInit {
  @ViewChild('input') inputTemplate!: TemplateRef<any>;
  
  formConfig: any = {
    perguntaForm: {
      formFieldType:'input',
      type: 'text'
    },
  };

  // 建立字符串到模板引用的映射表
  templateMap: Record<string, TemplateRef<any>> = {};

  ngAfterViewInit(): void {
    this.templateMap['input'] = this.inputTemplate;
  }
}
  1. 在模板中通过映射对象获取对应的TemplateRef:
<ng-template #template let-config="formConfig">
    <ng-container [ngTemplateOutlet]="templateMap[config['perguntaForm'].formFieldType]" [ngTemplateOutletContext]="{item: config['perguntaForm']}"></ng-container>
    <ng-container [ngTemplateOutlet]="input" [ngTemplateOutletContext]="{item: config['perguntaForm']}"></ng-container>
</ng-template>

这样就能通过配置中的字符串标识,动态渲染对应的模板了。

内容的提问来源于stack exchange,提问作者Juba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:55:55