Angular表格组件自定义单元格:匹配列ID显示ng-template实现问询
实现Angular ui-table的单个单元格自定义功能
我来帮你搞定这个自定义单元格的需求,咱们可以借助Angular的内容投影和模板引用能力,分几步就能实现匹配列ID显示自定义模板的效果:
1. 调整父组件的模板写法
首先给每个自定义的ng-template加上一个模板引用变量(比如#cellTemplate),这样子组件能精准识别并收集这些模板:
<ui-table [model]="tableModel"> <ng-template #cellTemplate matches="columnA" let-content="content"> {{content | commaSeparate}} </ng-template> <!-- 可以继续添加更多列的自定义模板 --> <ng-template #cellTemplate matches="columnB" let-content="content"> <span style="color: #2563eb">{{content}}</span> </ng-template> </ui-table>
2. 修改ui-table组件类
在组件类里,我们需要收集所有带#cellTemplate标记的模板,并建立「列ID-模板」的映射表,方便后续快速查找:
import { Component, Input, ContentChildren, QueryList, TemplateRef, OnInit, AfterContentInit } from '@angular/core'; @Component({ selector: 'ui-table', templateUrl: './ui-table.component.html' }) export class UiTableComponent implements OnInit, AfterContentInit { @Input() model: any; rowItems: any[] = []; // 收集父组件传入的所有带#cellTemplate标记的模板 @ContentChildren('cellTemplate') cellTemplates!: QueryList<TemplateRef<any>>; // 存储列ID到对应模板的映射 private templateMap = new Map<string, TemplateRef<any>>(); ngOnInit() { // 初始化行数据(和你之前的逻辑保持一致) this.rowItems = this.model.rows || []; } ngAfterContentInit() { // 遍历收集到的模板,根据matches属性建立映射关系 this.cellTemplates.forEach(template => { const columnId = template.elementRef.nativeElement.getAttribute('matches'); if (columnId) { this.templateMap.set(columnId, template); } }); } // 对外提供方法,根据列ID获取对应的自定义模板 getCellTemplate(columnId: string): TemplateRef<any> | null { return this.templateMap.get(columnId) || null; } }
3. 修改tbody的渲染逻辑
最后在tbody的td中,判断当前列是否有对应的自定义模板,有则渲染模板,没有则显示默认内容:
<tbody #tBody class="uitk-c-table__body"> <tr *ngFor="let row of rowItems" class="uitk-c-table__row"> <td *ngFor="let header of model.headers" class="uitk-c-table__cell"> <!-- 如果当前列有自定义模板,渲染模板并传递数据上下文 --> <ng-template *ngIf="getCellTemplate(header.id) as cellTemplate" [ngTemplateOutlet]="cellTemplate" [ngTemplateOutletContext]="{ content: row[header.id] }" ></ng-template> <!-- 没有自定义模板时,显示默认内容 --> <span *ngIf="!getCellTemplate(header.id)">{{row[header.id] || ''}}</span> </td> </tr> </tbody>
关键细节说明
@ContentChildren('cellTemplate'):专门用来捕获父组件传递进来的所有带指定标记的模板,是实现内容投影自定义的核心。ngAfterContentInit:必须在这个生命周期钩子中处理收集到的模板,因为此时内容投影已经完成,能安全访问到所有传入的模板。ngTemplateOutlet:动态渲染模板的指令,ngTemplateOutletContext负责给模板传递上下文数据,也就是你示例中let-content="content"里的content值。
这样一来,当matches属性的值和model.headers[x].id完全匹配时,就会自动渲染对应的自定义模板,完美实现单个单元格的自定义功能啦!
内容的提问来源于stack exchange,提问作者Get Off My Lawn
相关产品推荐
相关产品推荐

