Angular 15树形组件中实现可自定义重复内容投影的方法
Angular 15树形组件中实现可自定义重复内容投影的方法
嗨,这个需求其实和Angular Material Table的自定义单元格逻辑异曲同工,核心就是让父组件提供一个节点模板,树形组件遍历节点时复用这个模板并传入当前节点数据。我给你一步步拆解实现方案:
核心思路
通过「自定义结构化指令捕获用户提供的模板」+「组件内用ngTemplateOutlet渲染模板」,就能实现你想要的可自定义重复内容投影效果。
步骤1:创建捕获节点模板的结构化指令
首先需要一个指令来标记用户提供的自定义节点模板,这样树形组件能识别并获取这个模板:
import { Directive, TemplateRef } from '@angular/core'; @Directive({ selector: '[treeNode]' // 对应你想要的`*treeNode`语法 }) export class TreeNodeTemplateDirective { // 暴露模板引用,供树形组件调用 constructor(public templateRef: TemplateRef<any>) { } }
步骤2:修改树形组件,集成模板渲染
接下来在你的树形组件里,获取用户传入的模板,遍历节点时用模板渲染每个节点:
组件TS代码
import { Component, Input, ContentChild, TemplateRef } from '@angular/core'; import { TreeNodeTemplateDirective } from './tree-node-template.directive'; // 保留你原有的TreeNode接口 export interface TreeNode { id: number; value: any; parent: number|null; } @Component({ selector: 'tree-view', templateUrl: './tree-view.component.html' }) export class TreeViewComponent { @Input() data: TreeNode[] = []; // 通过ContentChild获取用户提供的自定义模板 @ContentChild(TreeNodeTemplateDirective) nodeTemplate!: TreeNodeTemplateDirective; }
组件HTML代码
替换原来的简单渲染逻辑,判断是否有自定义模板,有则用模板渲染,没有则显示默认内容:
<div class="tree-container"> <div *ngFor="let node of data; let i = index" class="tree-node"> <!-- 使用自定义模板渲染,把当前node作为上下文传递 --> <ng-container *ngIf="nodeTemplate; else defaultNode"> <ng-template [ngTemplateOutlet]="nodeTemplate.templateRef" [ngTemplateOutletContext]="{ $implicit: node, // 对应`let node`的变量 index: i // 可选:传递索引,用户可以用`let idx = index`获取 }"> </ng-template> </ng-container> <!-- 默认模板:当用户没提供自定义内容时显示 --> <ng-template #defaultNode> {{ node.value }} </ng-template> </div> </div>
步骤3:在父组件中使用自定义树形组件
现在你就能像预期那样使用树形组件了,自由自定义每个节点的内容:
<tree-view [data]="data"> <!-- 用*treeNode指令绑定模板,let node接收当前节点数据 --> <div *treeNode="let node; let idx = index"> <div class="custom-node"> 节点ID:{{node.id}} <span>自定义内容:{{node.value.name}}</span> <small>当前索引:{{idx}}</small> </div> </div> </tree-view>
关键细节说明
*treeNode="let node"是Angular结构化指令的语法糖,展开后等价于<ng-template treeNode let-node></ng-template>,我们的TreeNodeTemplateDirective会自动捕获这个模板。ngTemplateOutletContext用来传递模板需要的上下文数据,$implicit对应默认的变量(即let node),你还可以添加其他自定义变量(比如示例中的index)。- 别忘了在你的Angular模块中声明并导出
TreeNodeTemplateDirective和TreeViewComponent,否则会报错。
备注:内容来源于stack exchange,提问作者galalem
相关产品推荐
相关产品推荐

