Angular Slickgrid切换显隐时GroupBy表头行丢失问题求助
问题描述
在同一布局内使用多个Angular Slickgrid组件,通过*ngIf条件控制其中一个组件的显示与隐藏时,隐藏该组件后,当前显示的另一个Slickgrid的GroupBy表头行出现丢失情况。
使用版本:
- Angular 13.3.9
- Angular-Slickgrid 4.3.1
- slickgrid-universal 1.4.0
问题演示:
相关代码
HTML模板
<div class="grid-container"> <!-- 受控显示/隐藏的Slickgrid --> <angular-slickgrid *ngIf="showSecondGrid" [columnDefinitions]="secondColumnDefs" [gridOptions]="secondGridOptions" [dataset]="secondDataset"> </angular-slickgrid> <!-- 持续显示的Slickgrid(GroupBy表头丢失的目标组件) --> <angular-slickgrid [columnDefinitions]="mainColumnDefs" [gridOptions]="mainGridOptions" [dataset]="mainDataset" (onAngularGridCreated)="onMainGridCreated($event)"> </angular-slickgrid> </div> <button (click)="toggleSecondGrid()">切换第二个表格显示状态</button>
TS组件代码
import { Component } from '@angular/core'; import { Column, GridOption, AngularGridInstance } from '@slickgrid-universal/angular'; @Component({ selector: 'app-multi-grid', templateUrl: './multi-grid.component.html' }) export class MultiGridComponent { showSecondGrid = true; // 主表格配置 mainColumnDefs: Column[] = [ { id: 'title', name: 'Title', field: 'title', sortable: true }, { id: 'duration', name: 'Duration', field: 'duration', sortable: true }, { id: '%', name: '% Complete', field: 'percentComplete', sortable: true } ]; mainGridOptions: GridOption = { enableGrouping: true, enableSorting: true }; mainDataset = [/* 业务数据集 */]; // 受控表格配置 secondColumnDefs: Column[] = [/* 第二表格列定义 */]; secondGridOptions: GridOption = {/* 第二表格配置 */}; secondDataset = [/* 第二表格数据集 */]; private mainGridInstance!: AngularGridInstance; onMainGridCreated(gridInstance: AngularGridInstance) { this.mainGridInstance = gridInstance; } toggleSecondGrid() { this.showSecondGrid = !this.showSecondGrid; } }
解决方案
该问题源于*ngIf触发的DOM组件销毁/重建导致Slickgrid的GroupBy表头布局计算失效,以下是几种可行修复方案:
1. 切换显示状态后手动触发Grid重绘与布局更新
在切换组件显示状态后,延迟执行Grid的重绘和布局更新,确保DOM变动完成后恢复GroupBy表头:
toggleSecondGrid() { this.showSecondGrid = !this.showSecondGrid; // 用setTimeout确保DOM渲染完成后执行 setTimeout(() => { if (this.mainGridInstance?.slickGrid) { // 重新设置分组规则,触发GroupBy表头重绘 this.mainGridInstance.slickGrid.setGrouping(this.mainGridInstance.slickGrid.getGrouping()); // 更新整个Grid的布局尺寸 this.mainGridInstance.slickGrid.updateLayout(); } }, 0); }
2. 改用[hidden]替代*ngIf(避免组件销毁)
如果业务允许保留受控组件的状态,将*ngIf替换为[hidden],仅隐藏DOM节点而非销毁组件,避免大规模DOM变动:
<angular-slickgrid [hidden]="!showSecondGrid" [columnDefinitions]="secondColumnDefs" [gridOptions]="secondGridOptions" [dataset]="secondDataset"> </angular-slickgrid>
注意:此方法仅隐藏组件,受控组件仍会保持初始化状态,若不需要保留状态则不适用。
3. 监听布局变动事件(兜底方案)
在主Grid初始化时添加布局变动监听,强制触发布局更新:
onMainGridCreated(gridInstance: AngularGridInstance) { this.mainGridInstance = gridInstance; // 监听窗口resize事件,触发Grid布局更新 window.addEventListener('resize', () => { gridInstance.slickGrid.updateLayout(); gridInstance.slickGrid.setGrouping(gridInstance.slickGrid.getGrouping()); }); }
原理说明
Angular-Slickgrid的GroupBy表头依赖Grid的实时尺寸计算和DOM节点状态,*ngIf销毁组件时会触发页面布局重排,破坏原Grid的表头计算上下文。手动调用setGrouping和updateLayout可强制Grid重新计算表头位置与尺寸,恢复GroupBy行的显示。
内容的提问来源于stack exchange,提问作者Rajkumar
相关产品推荐
相关产品推荐

