Angular如何复用内容投影的重复HTML?拒绝新建组件
用TemplateRef复用Angular内容投影的公共HTML
当然可以通过TemplateRef配合Angular的模板指令,不用新建组件就能封装复用这段重复的HTML内容,具体实现方案如下:
1. 定义全局可复用模板
在根组件(如app.component.html)或者任意全局可访问的位置,用ng-template定义你需要复用的HTML片段,并添加模板引用变量:
<!-- app.component.html --> <ng-template #sharedWarningToast> <div style="font-size: large"><b>Warning message</b></div> </ng-template>
2. 跨组件共享模板(推荐方案)
如果需要在多个无关组件中复用这个模板,最便捷的方式是用一个共享服务来存储模板实例:
步骤2.1 创建共享模板服务
// template-shared.service.ts import { Injectable, TemplateRef } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class TemplateSharedService { // 存储警告提示模板 warningToastTemplate?: TemplateRef<any>; }
步骤2.2 在根组件中注册模板
把之前定义的模板赋值给服务,让其他组件可以获取到:
// app.component.ts import { Component, ViewChild, TemplateRef, OnInit } from '@angular/core'; import { TemplateSharedService } from './template-shared.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnInit { @ViewChild('sharedWarningToast') sharedWarningToast!: TemplateRef<any>; constructor(private templateService: TemplateSharedService) {} ngOnInit() { this.templateService.warningToastTemplate = this.sharedWarningToast; } }
3. 在目标组件中使用模板
在需要渲染<my-toast>的组件里,从服务获取模板,再通过ngTemplateOutlet把模板内容投影到<my-toast>中:
组件逻辑代码
// your-usage.component.ts import { Component } from '@angular/core'; import { TemplateSharedService } from './template-shared.service'; @Component({ selector: 'app-your-usage', templateUrl: './your-usage.component.html' }) export class YourUsageComponent { // 快捷获取模板 get warningToastTemplate() { return this.templateService.warningToastTemplate; } constructor(private templateService: TemplateSharedService) {} }
组件模板代码
<!-- your-usage.component.html --> <my-toast> <ng-container *ngTemplateOutlet="warningToastTemplate"></ng-container> </my-toast>
简化方案(同/父层级组件复用)
如果只是在同一父组件下的子组件中复用,不需要服务,直接通过@Input传递模板即可:
父组件模板
<!-- parent.component.html --> <ng-template #sharedWarningToast> <div style="font-size: large"><b>Warning message</b></div> </ng-template> <!-- 传递模板给子组件 --> <app-child-component [warningToastTemplate]="sharedWarningToast"></app-child-component>
子组件逻辑
// child.component.ts import { Component, Input } from '@angular/core'; import { TemplateRef } from '@angular/core'; @Component({ selector: 'app-child-component', templateUrl: './child.component.html' }) export class ChildComponent { @Input() warningToastTemplate?: TemplateRef<any>; }
子组件模板
<!-- child.component.html --> <my-toast> <ng-container *ngTemplateOutlet="warningToastTemplate"></ng-container> </my-toast>
这样就能在多个组件中复用同一段HTML内容,完全不需要新建额外组件。
内容的提问来源于stack exchange,提问作者Viking22
相关产品推荐
相关产品推荐

