Angular 7路由切换后公共SlickGrid组件空白问题求助
解决Angular路由切换后SlickGrid空白的问题
这个问题我之前也碰到过,核心原因是路由切换时组件销毁重建后,SlickGrid没有正确完成DOM绑定和渲染流程。下面是几个针对性的解决方案,亲测有效:
1. 确保在DOM就绪后初始化/刷新网格
SlickGrid依赖DOM元素存在才能正常渲染,ngOnInit执行时DOM可能还没完全准备好(尤其是路由切换后的组件重建场景)。改用ngAfterViewInit钩子配合手动刷新:
修改grid.component.ts,添加ViewChild获取SlickGrid实例,并在视图初始化后触发刷新:
import { Component, OnInit, AfterViewInit, ViewChild } from '@angular/core'; import { Column, GridOption } from 'angular-slickgrid'; import { AngularSlickGridComponent } from 'angular-slickgrid'; @Component({ selector: 'app-grid', templateUrl: './grid.component.html' }) export class GridComponent implements OnInit, AfterViewInit { columnDefinitions: Column[]; gridOptions1: GridOption; dataset1: any[]; // 获取SlickGrid组件实例 @ViewChild(AngularSlickGridComponent) angularSlickGrid!: AngularSlickGridComponent; ngOnInit(): void { this.initColumnsAndOptions(); this.mockData(); } ngAfterViewInit(): void { // 视图渲染完成后强制刷新网格 this.refreshGrid(); } initColumnsAndOptions() { this.columnDefinitions = [ {id: 'title', name: 'Title', field: 'title', sortable: true}, {id: 'duration', name: 'Duration (days)', field: 'duration', sortable: true}, {id: '%', name: '% Complete', field: 'percentComplete', sortable: true}, {id: 'start', name: 'Start', field: 'start'}, {id: 'finish', name: 'Finish', field: 'finish'}, {id: 'effort-driven', name: 'Effort Driven', field: 'effortDriven', sortable: true} ]; this.gridOptions1 = { enableAutoResize: true, enableSorting: true, // 可选:明确自动调整的配置,适配DOM尺寸 autoResize: { minWidth: 800, minHeight: 300 } }; } mockData() { const mockDataset = []; for (let i = 0; i < 20; i++) { const randomYear = 2000 + Math.floor(Math.random() * 10); const randomMonth = Math.floor(Math.random() * 11); const randomDay = Math.floor((Math.random() * 29)); const randomPercent = Math.round(Math.random() * 100); mockDataset[i] = { id: i, title: 'Task ' + i, duration: Math.round(Math.random() * 100) + '', percentComplete: randomPercent, start: `${randomMonth}/${randomDay}/${randomYear}`, finish: `${randomMonth}/${randomDay}/${randomYear}`, effortDriven: (i % 5 === 0) }; } // 用扩展运算符创建新数组,触发Angular变更检测 this.dataset1 = [...mockDataset]; } // 手动刷新网格的方法 refreshGrid() { if (this.angularSlickGrid?.slickGrid) { // 强制重绘网格内容 this.angularSlickGrid.slickGrid.render(); // 重新计算布局,适配当前DOM尺寸 this.angularSlickGrid.resizeGrid(); } } }
2. 监听路由激活事件,确保组件重建时刷新
当路由切换回组件时,可以监听路由事件,触发数据重新加载和网格刷新:
在grid.component.ts中注入ActivatedRoute,并订阅路由变化:
import { ActivatedRoute } from '@angular/router'; constructor(private route: ActivatedRoute) {} ngOnInit(): void { this.initColumnsAndOptions(); // 监听路由变化,每次组件激活时重新加载数据并刷新 this.route.url.subscribe(() => { this.mockData(); // 延迟执行确保DOM更新完成 setTimeout(() => this.refreshGrid(), 0); }); }
3. 清理SlickGrid实例,避免内存泄漏(可选)
为了更严谨,可以在组件销毁时清理SlickGrid实例,避免内存泄漏,同时确保下次重建时完全初始化:
ngOnDestroy(): void { if (this.angularSlickGrid?.slickGrid) { this.angularSlickGrid.slickGrid.destroy(); } }
为什么这些方法有效?
ngAfterViewInit:确保DOM元素已经渲染完成,此时调用SlickGrid的刷新方法能保证网格正确绑定到DOM节点。- 数组引用变更:Angular的变更检测对数组引用变化更敏感,用
[...mockDataset]创建新数组,能触发组件重新渲染。 - 手动刷新网格:路由切换后DOM可能发生尺寸变化,调用
render()和resizeGrid()能强制SlickGrid重新计算布局并绘制内容。
内容的提问来源于stack exchange,提问作者Subham
相关产品推荐
相关产品推荐

