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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 11:42:41