如何在Angular中实现可展开多级网格(无需插件)
实现Angular多级嵌套网格(无插件版)
我明白你的需求啦,不用任何第三方插件,纯Angular自带功能就能搞定这个多级展开的网格。核心思路是给每个数据项维护子项列表和展开状态,再用递归模板来渲染嵌套结构。下面一步步来实现:
第一步:调整数据结构
首先,我们需要给每个数据项添加两个属性:
children: []:用来存储当前项的子数据isExpanded: boolean:控制当前项的子网格是否展开
在组件初始化顶层数据的时候,就给每个项加上这两个属性:
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-nested-grid', templateUrl: './nested-grid.component.html', styleUrls: ['./nested-grid.component.css'] }) export class NestedGridComponent { values: any[] = []; constructor(private http: HttpClient) { // 模拟初始加载的顶层数据 const initialData = [ {id:1, desc:'test', level: 0}, {id:2, desc:'testing',level: 0} ]; // 给每个项添加子项数组和展开状态 this.values = initialData.map(item => ({ ...item, children: [], isExpanded: false })); } getTerms(parentId: number, parentItem: any) { // 如果已经展开,就切换折叠状态 if (parentItem.isExpanded) { parentItem.isExpanded = false; return; } // 调用接口获取子项数据 this.http.get(`/get/Term/${parentId}`).subscribe((childData: any[]) => { // 给子项也加上children和isExpanded const formattedChildren = childData.map(child => ({ ...child, children: [], isExpanded: false })); // 将子项赋值给父项的children数组 parentItem.children = formattedChildren; // 切换展开状态 parentItem.isExpanded = true; }); } }
第二步:用递归模板渲染嵌套结构
Angular的ng-template支持递归调用,我们可以用它来渲染任意层级的子网格。模板结构如下:
<table class="nested-table"> <thead> <tr> <th>Check</th> <th>Result</th> </tr> </thead> <tbody> <!-- 递归模板入口:渲染顶层数据 --> <ng-container *ngTemplateOutlet="rowTemplate; context: { $implicit: values }"></ng-container> <!-- 定义递归渲染的模板 --> <ng-template #rowTemplate let-items> <tr *ngFor="let item of items"> <td> <label class="checkbox"> <input type="checkbox"> </label> <!-- 点击ID时调用getTerms,传入父项本身 --> <a (click)="getTerms(item.id, item)">{{item.id}}</a> </td> <td>{{item.desc}}</td> </tr> <!-- 如果当前项展开且有子项,渲染子表格 --> <tr *ngIf="item.isExpanded && item.children.length > 0"> <td colspan="2"> <!-- 子表格,用缩进区分层级 --> <table class="child-table"> <tbody> <!-- 递归调用模板渲染子项 --> <ng-container *ngTemplateOutlet="rowTemplate; context: { $implicit: item.children }"></ng-container> </tbody> </table> </td> </tr> </ng-template> </tbody> </table>
第三步:添加样式优化显示效果
为了让子网格有明显的层级缩进,我们可以加一点CSS:
.nested-table { width: 100%; border-collapse: collapse; } .nested-table th, .nested-table td { border: 1px solid #ddd; padding: 8px; } .child-table { width: 100%; border-collapse: collapse; margin-left: 20px; /* 子表格缩进 */ } .child-table td { border: none; border-bottom: 1px solid #eee; }
关键逻辑说明
- 数据结构扩展:通过给每个项添加
children和isExpanded,我们能追踪每个节点的子数据和展开状态,这是实现嵌套的核心。 - 递归模板:
ng-template的递归调用让我们可以处理任意层级的嵌套,不用手动写多层*ngFor。 - 展开/折叠切换:点击ID时,如果已经展开就直接折叠;如果没展开,就请求子数据并展开。
这样就能实现你要的效果:点击顶层ID加载子项并展开子网格,子项ID点击后继续加载下一级,无限嵌套都没问题~
内容的提问来源于stack exchange,提问作者Tavish Aggarwal
相关产品推荐
相关产品推荐

