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

Angular 6+ angular calendar如何从独立文件加载完整ng-template模板

问题描述

我在项目中使用 angular calendar 组件并做了大量自定义,自定义逻辑通过 <ng-template> 实现,目前所有模板都放在同一个文件中已经难以维护。

原有简化代码示例

app.component.html

<!-- 从独立文件加载该部分 -->
<ng-template
  #currentTimeMarkerTemplate
  let-columnDate="columnDate"
  let-dayStartHour="dayStartHour"
  let-dayStartMinute="dayStartMinute"
  let-dayEndHour="dayEndHour"
  let-dayEndMinute="dayEndMinute"
  let-isVisible="isVisible"
  let-topPx="topPx"
>
  <div
    class="cal-current-time-marker"
    *ngIf="isVisible && showMarker"
    [style.top.px]="topPx"
  ></div>
</ng-template>
<!-- 从独立文件加载该部分 -->

<!-- 调用上述模板引用 -->
<mwl-calendar-week-view
  [currentTimeMarkerTemplate]="currentTimeMarkerTemplate"
  [viewDate]="viewDate"
  [dayStartHour]="dayStartHour"
  [dayEndHour]="dayEndHour"
>
</mwl-calendar-week-view>

尝试的方案与报错

我尝试创建 app-my-template.component.html,将 <ng-template> 标签移入该文件,随后修改 app.component.html 如下:

<app-my-template #external_template></app-my-template>
<mwl-calendar-week-view
  [currentTimeMarkerTemplate]="external_template"
  [viewDate]="viewDate"
  [dayStartHour]="dayStartHour"
  [dayEndHour]="dayEndHour"
>
</mwl-calendar-week-view>

运行时报错如下:

"Type 'MyTemplate' is missing the following properties from type 'TemplateRef': elementRef, createEmbeddedView"

我也尝试过其他公开方案,但这些方案的 <ng-template> 部分放在组件外部,不适用我的场景,因为我的模板关联了大量自身绑定变量。
我的问题是:如何从外部文件加载包含标签本身在内的完整 <ng-template> 模板?

解决方案

报错的核心原因是:你直接传入了自定义组件的实例,而 angular-calendar 的 currentTimeMarkerTemplate 输入要求的是 TemplateRef 类型的模板引用对象,两者类型不匹配。
按以下步骤实现即可:

  1. 编写独立模板组件的逻辑与模板
    首先编写 app-my-template.component.ts,通过 ViewChild 拿到内部 ng-template 的引用并对外暴露,模板自身的绑定变量也可以封装在该组件内部维护:
import { Component, ViewChild, TemplateRef } from '@angular/core';

@Component({
  selector: 'app-my-template',
  templateUrl: './app-my-template.component.html'
})
export class MyTemplateComponent {
  // 与模板内ng-template的引用名对应
  @ViewChild('currentTimeMarkerTemplate', { static: true }) currentTimeTemplate!: TemplateRef<any>;
  
  // 模板自身绑定的变量都可以放在这里维护
  public showMarker = true;
}

app-my-template.component.html 内容就是你拆分出来的 ng-template 代码:

<ng-template
  #currentTimeMarkerTemplate
  let-columnDate="columnDate"
  let-dayStartHour="dayStartHour"
  let-dayStartMinute="dayStartMinute"
  let-dayEndHour="dayEndHour"
  let-dayEndMinute="dayEndMinute"
  let-isVisible="isVisible"
  let-topPx="topPx"
>
  <div
    class="cal-current-time-marker"
    *ngIf="isVisible && showMarker"
    [style.top.px]="topPx"
  ></div>
</ng-template>
  1. 修改父组件的调用逻辑
    在父组件的 app.component.html 中,传入子组件暴露的 TemplateRef 属性即可:
<app-my-template #externalTemplate></app-my-template>
<mwl-calendar-week-view
  [currentTimeMarkerTemplate]="externalTemplate.currentTimeTemplate"
  [viewDate]="viewDate"
  [dayStartHour]="dayStartHour"
  [dayEndHour]="dayEndHour"
>
</mwl-calendar-week-view>

如果有多个自定义模板需要拆分,只需要在独立组件内给每个 ng-template 设置不同的引用名,分别用 ViewChild 暴露为不同属性即可,维护起来非常灵活。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 20:48:03