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 类型的模板引用对象,两者类型不匹配。
按以下步骤实现即可:
- 编写独立模板组件的逻辑与模板
首先编写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>
- 修改父组件的调用逻辑
在父组件的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

