在 ag-grid 内安装一个 mat-accordion
Posted
技术标签:
【中文标题】在 ag-grid 内安装一个 mat-accordion【英文标题】:Fitting a mat-accordion inside ag-grid 【发布时间】:2020-12-07 03:04:35 【问题描述】:我有一个相当标准的带有嵌套组件的 ag-grid 设置,如下所示:
import Component from '@angular/core';
import * as agGrid from 'ag-grid-community';
import NestedMatExpansionPanelComponent from './nested-mat-expansion-panel/nested-mat-expansion-panel.component';
@Component(
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
)
export class AppComponent
title = 'aggrid-material-expansion-panel';
dataToShow = [
name: 'name1', companyCountry: 'UK', reference: 'Ref 1' ,
name: 'name2', companyCountry: 'Germany', reference: 'Ref 2' ,
name: 'name3', companyCountry: 'France', reference: 'Ref 3' ,
name: 'name4', companyCountry: 'UK', reference: 'Ref 4' ,
name: 'name5', companyCountry: 'USA', reference: 'Ref 5' ,
];
columnDefs = [
// tslint:disable-next-line: max-line-length
headerName: 'Name', colId: 'name', cellRenderer: 'nestedMatExpansionPanelRenderer', filter: false, sortable: false ,
headerName: 'Country', field: 'companyCountry', sortable: true, filter: true ,
headerName: 'Reference', field: 'reference', sortable: true, filter: true
];
// agG_rid
gridApi: agGrid.GridApi;
gridColumnApi: agGrid.ColumnApi;
gridOptions: agGrid.GridOptions = ;
public defaultColDef: any;
public columnTypes: any;
public context: any;
public frameworkComponents: any;
public sortingOrder: any;
constructor()
this.initTable();
public onGridReady(params: any)
// this.gridApi = this.gridOptions.api;
// this.gridColumnApi = this.gridOptions.columnApi;
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
public initTable(): void
this.defaultColDef =
flex: 1,
autoHeight: true,
editable: false,
enableBrowserTooltips: true,
resizable: true,
filter: 'agTextColumnFilter',
suppressMenu: true,
floatingFilterComponentParams: suppressFilterButton: true ,
filterParams: newRowsAction: 'keep' ,
sortable: true,
;
this.columnTypes =
numericColumn: filter: 'agnumericColumnFilter' ,
dateColumn:
filter: 'agDateColumnFilter',
filterParams:
newRowsAction: 'keep',
comparator(filterLocalDateAtMidnight, cellValue)
const dateParts = cellValue.split('/');
const day = Number(dateParts[2]);
const month = Number(dateParts[1]) - 1;
const year = Number(dateParts[0]);
const cellDate = new Date(day, month, year);
if (cellDate < filterLocalDateAtMidnight)
return -1;
else if (cellDate > filterLocalDateAtMidnight)
return 1;
else
return 0;
;
this.sortingOrder = ['desc', 'asc'];
this.context = componentParent: this ;
this.frameworkComponents =
nestedMatExpansionPanelRenderer: NestedMatExpansionPanelComponent,
;
public onRowClicked($event)
//
如你所见,我有
autoHeight: true,
所以每一行都应该根据嵌入式手风琴的展开状态自动获得正确的高度,但是该行的输出高度计算不正确:
如何根据嵌入式扩展面板的状态自动调整每行的高度,以便在打开或关闭每行内的扩展面板时不会有任何空余空间?
Link to the repository
【问题讨论】:
【参考方案1】:基本上,您遇到的问题是 MatExpansionPanel
和 autoHeight
如何在 ag-grid 中计算的综合问题。
使用 autoHeight 他们从单元格中获取内容,并将其放在一个临时的不可见元素中,可能位于 document.body
元素中。问题是此时没有对元素应用正确的样式,它显示了您所面对的高度。所以,autoHeight
不是这里的解决方案,应该设置为false
。
那么如何实现手动高度计算。 Ag-grid 在node
上有一个setRowHeight
属性。您可以使用它来设置高度。从那里需要通知网格 API,所有行都改变了它们的高度,并且可以在此基础上重新计算,方法是调用 onRowHeightChanged()
。获得这种通信的一种方法是使用普通服务:
@Injectable()
export class GridService
readonly updateHeight$ = new Subject<void>();
从您在模板中创建 ag-grid 的组件中,您应该将此服务器添加到 providers 数组并监听主题(使用 debounce 以确保最初计算所有行):
@Component(
// ...,
providers: [GridService]
)
export class GridComponent
gridApi: agGrid.GridApi;
constructor(private gs: GridService)
this.gs.updateHeight$.pipe(
debounceTime(1)
).subscribe(() =>
this.gridApi?.onRowHeightChanged();
);
onGridReady(params: any)
this.gridApi = params.api;
现在我们需要在单元格渲染器框架组件中实现以下逻辑:
export class ExpansionPanelComponent implements ICellRendererAngularComp, AfterViewInit
public params: ICellRendererParams;
constructor(private el: ElementRef<HTMLElement>, private gs: GridService)
agInit(params: ICellRendererParams): void
this.params = params;
ngAfterViewInit(): void
// inside setTimeout because the accordion is not properly sized (bug) and it will be too big
setTimeout(() => this.updateHeight());
updateHeight(): void
// inside setTimeout because the accordion is not properly sized (bug) and it will be too big
setTimeout(() =>
this.params?.node.setRowHeight(this.el.nativeElement.offsetHeight);
this.gs.updateHeight$.next();
);
refresh(params: any): boolean
return false;
我创建了一个有效的拉取请求here
要删除左侧的填充,您可以将以下内容添加到您的 columnDefs 数组中:
columnDefs = [
//...,
cellRenderer: 'nestedMatExpansionPanelRenderer',
cellStyle: 'padding-left': 0
,
// ...
]
【讨论】:
@Excellent answer Poul,你几乎做到了。最后一点:您能否更新您的答案,以便面板的左右两侧 [图像中的“B”区域] 不会有任何空白? @MHOOS 您可以通过在列定义中添加cellStyle
(或cellClass
,如果您想重新使用它)轻松解决此问题。我会更新我的答案以上是关于在 ag-grid 内安装一个 mat-accordion的主要内容,如果未能解决你的问题,请参考以下文章