在选项卡菜单显示的两个单独的ag-Grid上使用ag-Grid的sizeColumnsToFit()时,警告“网格零宽度”

时间:2019-01-04 11:24:26

标签: angular tabs ag-grid ag-grid-ng2 ag-grid-angular

调整ag-Grid的大小(更改浏览器窗口的大小)并在两个选项卡之间切换时,获得以下警告:

  

ag-Grid:尝试调用sizeColumnsToFit(),但网格又回来了   宽度为零,也许网格在屏幕上还不可见?

我在Stackblitz中再现了这种情况:

https://angular-jpmxjy.stackblitz.io/

这是测试应用程序的组成:

  • PrimeNG p-tabMenu组件:header.component
  • ag-Grid位于 组件:delleverancer.component和legancer.component。

您会在chrome开发工具中看到警告错误, 当您调整网格大小并在tabMenu“ Leverancer”和“ Delleverancer”之间切换时。

您可以在此处查看代码:

https://stackblitz.com/edit/angular-jpmxjy

如何清除此不必要的警告错误?

enter image description here

3 个答案:

答案 0 :(得分:3)

这类错误通常意味着您的应用程序中存在内存泄漏。

查看代码后,我注意到您如何订阅window:resize事件

window.addEventListener("resize", function () { ...

您应该知道,即使在销毁组件之后,该订阅仍将存在。

您可以在removeEventListener钩中写入ngOnDestroy。但是为此,您必须保留对原始附加功能的引用。更好的方法是使用专用的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

答案 1 :(得分:3)

旧线程,但是对于反应的答案和将来的受害者,我遇到了同样的问题,问题是使用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>
 )

答案 2 :(得分:0)

这对我有帮助

ngOnDestroy() {
    try { 
        if (this.gridApi) {
            this.gridApi.destroy();
            this.gridApi = false;
        }

    } catch (error) {

    }
}