在两个单独的 ag-Grid 上使用 ag-Grid 的 sizeColumnsToFit() 时警告“网格零宽度”,由选项卡菜单显示
Posted
技术标签:
【中文标题】在两个单独的 ag-Grid 上使用 ag-Grid 的 sizeColumnsToFit() 时警告“网格零宽度”,由选项卡菜单显示【英文标题】:Warning 'grid zero width' when using ag-Grid's sizeColumnsToFit() on two separate ag-Grids, displayed by a tab menu 【发布时间】:2019-05-30 23:18:50 【问题描述】:在调整 ag-Grid 的大小(更改浏览器窗口的大小)并在两个选项卡之间切换时收到以下警告:
ag-Grid: 试图调用 sizeColumnsToFit() 但网格又回来了 宽度为零,屏幕上可能还看不到网格吗?
我已经在 Stackblitz 中重现了这种情况:
https://angular-jpmxjy.stackblitz.io/
这里是测试应用的组成:
PrimeNG p-tabMenu 在组件:header.component ag-Grid 在 组件:delleverancer.component 和leverancer.component。您会在 chrome 开发工具中看到警告错误, 当您调整网格大小并在 tabMenu 'Leverancer' 和 'Delleverancer' 之间切换时。
您可以在此处查看代码:
https://stackblitz.com/edit/angular-jpmxjy
如何删除这个不需要的警告错误?
【问题讨论】:
【参考方案1】:此类错误通常意味着您的应用程序中存在内存泄漏。
查看您的代码后,我注意到您如何订阅 window:resize
事件
window.addEventListener("resize", function () ...
您应该知道,即使在组件被销毁后,此订阅仍然存在。
您可以在 ngOnDestroy
挂钩中写入 removeEventListener
。但是为此,您必须保留对原始附加功能的引用。更好的方法是使用专门的 Angular @HostListener
装饰器来负责removeEventListener
:
@HostListener('window:resize')
onResize()
if (!this.gridApi) return;
setTimeout(() =>
this.gridApi.sizeColumnsToFit();
);
Forked Stackblitz
为了不重复自己,您可以创建如下指令:
ag-grid-resize.directive.ts
import Directive, HostListener from '@angular/core';
@Directive(
selector: '[ag-grid-resize]'
)
export class AgGridResizeDirective
private gridApi;
@HostListener('window:resize')
onResize()
if (!this.gridApi) return;
setTimeout(() =>
this.gridApi.sizeColumnsToFit();
);
@HostListener('gridReady', ['$event'])
onGridReady(params)
this.gridApi = params.api;
params.api.sizeColumnsToFit();
现在,您需要添加该行为的只是将属性添加到您的网格:
<ag-grid-angular
...
ag-grid-resize <============
>
</ag-grid-angular>
Stackblitz Example
【讨论】:
大概是这样回答的。不会改变你写的一个字。不错的答案。喜欢@HostListener 和指令的额外建议 您好,如果我正在寻找类似的 React 版本,您能建议我如何解决这个问题吗? 不工作,显示相同的错误,gridPanel.js:814 ag-Grid: 试图调用 sizeColumnsToFit() 但网格以零宽度返回,可能网格在屏幕?即使我在 onFirstDataRendered 事件后调用 sizetoFit @DevinMcQueeney 你能在 stackblitz 中重现它吗?【参考方案2】:旧线程,但对于反应答案和未来的受害者,我遇到了同样的问题,问题是用 componentWillUnmount 清理事件侦听器。
要查看您的事件侦听器发生了什么,请使用(在 Chrome 中)getEventListeners(window) 并观察您的组件如何添加它们,但在您更改页面等时不要删除它们。在实施下面的解决方案后,您应该会看到事件当你的组件被销毁时,监听器会被移除。
需要为监听器使用一个函数,以便您有适当的参考来删除。
假设基于类的方法:
export class someAgGrid extends Component your brilliance
componentWillUnmount()
window.removeEventListener('resize', this.daListener);
;
daListener = () =>
if (!this.gridApi) return;
setTimeout(() => this.gridApi.sizeColumnsToFit(); , 200);
;
firstDataRendered = (params) =>
this.gridApi = params.api;
this.gridApi.sizeColumnsToFit();
window.addEventListener('resize', this.daListener);
;
在渲染函数中:
return (
<div className='ag-theme-material'>
<AgGridReact
...your stuff
onFirstDataRendered=this.firstDataRendered
/>
</div>
)
【讨论】:
setTimeout(() => this.gridApi.sizeColumnsToFit(); , 200);
有什么用?您已经在 firstDataRendered
中调用了 sizeColumnsToFit()
。【参考方案3】:
这对我有帮助
ngOnDestroy()
try
if (this.gridApi)
this.gridApi.destroy();
this.gridApi = false;
catch (error)
【讨论】:
【参考方案4】:在使用 Bootstrap Angular 选项卡时遇到此问题,但其他库的解决方案应该类似。希望这可以帮助其他仍在努力寻找解决方案的人。
-
每个 ag-grid 都需要有 onGridReady 函数。
显示网格的第一个选项卡没有问题,因为它在 DOM 中呈现时调整列大小以适应它。
对于其他选项卡中的网格,在选项卡更改时触发的事件中调用 sizeColumnsToFit()(对于 Bootstrap 选择选项卡)。检查其他相应库的文档。
html:
<tabset type="pills">
<tab heading="heading1" id="tab1">
<ag-grid-angular
class="ag-theme-balham ag-grid-table"
[rowData]="data1$ | async"
[defaultColDef]="defaultColDef"
[columnDefs]="columnDefs1"
(gridReady)="onGridReady1($event)"
>
</ag-grid-angular>
</tab>
<tab heading="heading2" id="tab2" (selectTab)="onSelect($event)">
<ag-grid-angular
class="ag-theme-balham ag-grid-table"
[rowData]="data2$ | async"
[defaultColDef]="defaultColDef"
[columnDefs]="columnDefs2"
(gridReady)="onGridReady2($event)"
>
</ag-grid-angular>
</tab>
<tabset>
打字稿:
import Component, OnInit from '@angular/core';
import BehaviorSubject from 'rxjs';
import ColDef, GridReadyEvent from 'ag-grid-community';
import TabDirective from 'ngx-bootstrap/tabs';
@Component(
selector: 'app-tabs',
templateUrl: './tabs.component.html',
styleUrls: ['./tabs.component.css'],
)
export class TabsetComponent implements OnInit
data1$ = new BehaviorSubject<any[]>([]);
data2$ = new BehaviorSubject<any[]>([]);
private gridApi2;
private gridColumnApi2;
defaultColDef: ColDef =
sortable: true,
filter: true,
resizable: true,
;
columnDefs1: ColDef[] = [
headerName: 'Category', field: 'category' ,
headerName: 'Name', field: 'name' ,
];
columnDefs2: ColDef[] = [
headerName: 'Module', field: 'module' ,
headerName: 'Approval', field: 'approvalName' ,
];
constructor()
ngOnInit(): void
// Event fired on tab change, needed only for tabs that are not rendered on page laod
onSelect(event: TabDirective)
switch (event.heading)
case 'heading2':
return this.gridApi2.sizeColumnsToFit();
default:
return;
// tab displayed on page load can call sizeColumnsToFit() directly
onGridReady1(event: GridReadyEvent)
event.api.sizeColumnsToFit();
onGridReady2(event: GridReadyEvent)
this.gridApi2 = event.api;
this.gridColumnApi2 = event.columnApi;
【讨论】:
以上是关于在两个单独的 ag-Grid 上使用 ag-Grid 的 sizeColumnsToFit() 时警告“网格零宽度”,由选项卡菜单显示的主要内容,如果未能解决你的问题,请参考以下文章