Angular
ag-Grid
SD希望可以在grid上加上Drill down
的功能(點擊資料,可以展開/收起詳細資料)。
網路上找到的套件Kendo
,看起來有支援Angular做Detail功能的套件,且有兩種樣板可以選擇。
❌現階段不希望多載入一個套件來做這件事,因此就沒有多研究此套件了。
A1目前是使用ag-Grid的套件來實現grid的功能,但ag-Grid提供相符SD需求的功能是需要付費的。
✔必須想辦法以不付費的方式來達到此效果。
agGrid
- onCellClicked()。
- Full Width Rows。
- HTML+CSS。
💡要使列(row)為全屏寬度(fullWidth)必須實現isFullWidthCell及提供fullWidthCellRenderer
使用isFullWidthCell告知哪些列是為全屏寬度的。
this.gridOptions.api.setRowData(data)後,每列都會跑一次isFullWidthCell。
balance-list.component.ts
isFullWidthCell = function (rowNode) {
return typeof (rowNode.data.detail) === 'string';
};
提供一個fullWidthCellRenderer,讓grid cellRenderer在進行fullWidth渲染時要使用什麼。
balance-list.component.ts
fullWidthCellRenderer = (params) => {
let cssClass;
// rowPinned 是凍結列的意思
if (params.node.rowPinned) {
cssClass = 'example-full-width-pinned-row';
} else {
cssClass = 'example-full-width-row';
}
// Create new DOM element
const eDiv = document.createElement('div');
eDiv.innerHTML = `<div class="${cssClass}">${params.data.detail}</div>`;
return eDiv.firstChild;
}
設定row高度用,可依自己需求指定高度。
balance-list.component.ts
getRowHeight = function (params) {
if (!params) {
return 30;
}
return params.data.detail ? params.data.count * 30 : 30;
};
單點擊
a1-grid.component.ts
this.gridOptions.onCellClicked = (event) => {
this.onCellClicked.emit(event);
};
偵測到點擊後,將資料整理成HTML樣式的字串,在這邊就要將詳細資料的畫面準備好。
CSS世騏學長設計,HTML套世騏學長提供。
balance-list.component.ts
onRowClicked(params) {
// 詳細資料(Detail)
/*準備資料 #依點擊Type & ReasonName為依據*/
const rowData: BalanceList = params.data;
const rowDetail = this.balanceList.filter(item => item.Type == rowData.Type && item.ReasonName == rowData.ReasonName && !!item.BShortName);
/*資料畫面 #detail:放HTML(畫面+資料) #count:依筆數給高度*/
const gridData = this.a1Grid.getAllGridData();
const gridDetail = { detail: '', count: 0};
/*資料畫面 #身體資料*/
rowDetail.forEach((detail, i) => {
/*規格上的TenantAmount = TotalAmount*/
gridDetail.detail +=
`<tr>
<td style="width: 100px;">${detail.BShortName}</td>
<td style="width: 100px;">${detail.TenantQty}</td>
<td style="width: 100px;">${this.decimalPipe.transform(detail.TotalAmount, '')}</td>
</tr>`;
gridDetail.count = i + 2;
});
/*資料畫面 #標題名稱*/
gridDetail.detail =
`<table>
<tbody>
<tr>
<th style="width: 100px;">分店簡稱</th>
<th style="width: 100px;">數量</th>
<th style="width: 100px;">金額</th>
</tr>
${gridDetail.detail}
</tbody>
</table>`;
// 詳細資料收起|展開
/*收起*/
if (gridData[params.rowIndex + 1] && gridData[params.rowIndex + 1].detail) {
gridData.splice(params.rowIndex + 1, 1);
} else if (rowDetail.length > 0) {
/*展開*/
gridData.splice(params.rowIndex + 1, 0, gridDetail);
}
this.a1Grid.setGridRowData(gridData);
}