Ag-grid:如何在主从表中实现setQuickFilter并获取筛选结果数量
Ag-Grid主表+子表联动快速筛选及结果统计方案
一、解决核心问题
针对你遇到的主表与子表筛选不同步、子表无匹配时主表行被隐藏的问题,通过主表外部过滤+子表同步筛选的方式实现需求:主表行只要自身匹配或子表有匹配数据就保留,同时子表只显示匹配内容;并支持统计筛选后的总结果数。
二、实现代码示例
HTML部分
<input type="text" id="filter-text-box" placeholder="输入关键词搜索..." oninput="onQuickFilterChanged()"> <div id="myGrid" style="height: 600px; width: 100%;" class="ag-theme-alpine"></div> <!-- 可选:显示统计结果 --> <div id="count-display" style="margin-top: 10px;"></div>
JavaScript部分
let gridApi; let quickFilterText = ''; // 主表列定义 const masterColumnDefs = [ { field: 'id', headerName: '用户ID' }, { field: 'name', headerName: '用户名' }, { field: 'age', headerName: '年龄' } ]; // 主表配置 const gridOptions = { columnDefs: masterColumnDefs, masterDetail: true, detailRowHeight: 220, // 子表配置 detailCellRendererParams: { detailGridOptions: { columnDefs: [ { field: 'product', headerName: '商品' }, { field: 'quantity', headerName: '数量' }, { field: 'price', headerName: '单价' } ], onGridReady: params => { // 子表初始化时同步筛选文本 params.api.setQuickFilter(quickFilterText); } }, // 加载子表数据 getDetailRowData: params => { params.successCallback(params.data.orders); } }, // 启用外部过滤(结合子表匹配逻辑) isExternalFilterPresent: () => quickFilterText.trim() !== '', // 自定义主表行过滤规则 doesExternalFilterPass: node => { const lowerText = quickFilterText.toLowerCase(); // 1. 判断主表行自身是否匹配 const selfMatches = node.data.name.toLowerCase().includes(lowerText) || node.data.id.toString().includes(quickFilterText) || node.data.age.toString().includes(quickFilterText); if (selfMatches) return true; // 2. 判断子表数据中是否有匹配项 const hasMatchingDetail = node.data.orders.some(order => { return order.product.toLowerCase().includes(lowerText) || order.quantity.toString().includes(quickFilterText) || order.price.toString().includes(quickFilterText); }); return hasMatchingDetail; }, onGridReady: params => { gridApi = params.api; // 加载模拟主表数据 gridApi.setRowData(getMockMasterData()); }, // 子表创建后同步筛选文本 onDetailGridCreated: params => { params.detailGridApi.setQuickFilter(quickFilterText); } }; // 模拟主表数据(含子表订单数据) function getMockMasterData() { return [ { id: 1, name: 'Alice', age: 30, orders: [{ product: 'Laptop', quantity: 1, price: 999 }, { product: 'Mouse', quantity: 2, price: 25 }] }, { id: 2, name: 'Bob', age: 25, orders: [{ product: 'Phone', quantity: 1, price: 699 }, { product: 'Headphones', quantity: 1, price: 149 }] }, { id: 3, name: 'Charlie', age: 35, orders: [{ product: 'Tablet', quantity: 1, price: 399 }, { product: 'Charger', quantity: 2, price: 15 }] } ]; } // 筛选文本变化时触发联动更新 function onQuickFilterChanged() { quickFilterText = document.getElementById('filter-text-box').value.trim(); // 更新主表外部过滤 gridApi.onFilterChanged(); // 同步所有子表的快速筛选 gridApi.forEachDetailGridInfo(detailGridInfo => { detailGridInfo.api.setQuickFilter(quickFilterText); }); // 更新筛选结果统计 updateFilteredCount(); } // 计算并显示筛选后的总数 function updateFilteredCount() { // 主表可见行数(符合条件的主表行) const masterCount = gridApi.getDisplayedRowCount(); // 所有展开子表的可见行数总和 let detailCount = 0; gridApi.forEachDetailGridInfo(detailGridInfo => { detailCount += detailGridInfo.api.getDisplayedRowCount(); }); const totalCount = masterCount + detailCount; // 显示统计结果到页面 document.getElementById('count-display').textContent = `筛选结果总数:${totalCount}(主表${masterCount}行,子表${detailCount}行)`; } // 初始化表格 document.addEventListener('DOMContentLoaded', () => { const gridDiv = document.getElementById('myGrid'); new agGrid.Grid(gridDiv, gridOptions); });
三、关键逻辑说明
- 主表过滤规则:通过
doesExternalFilterPass自定义判断逻辑,主表行只要自身匹配筛选文本,或子表数据中有匹配项,就会被保留显示,解决了原方案中子表无匹配时主表行被隐藏的问题。 - 子表同步筛选:在子表初始化、筛选文本变化时,通过
forEachDetailGridInfo遍历所有子表,同步设置快速筛选文本,确保子表只显示匹配内容。 - 结果统计:分别获取主表可见行数、所有展开子表的可见行数,累加得到总结果数,可根据需求调整统计维度(比如只统计主表符合条件的行数)。
内容的提问来源于stack exchange,提问作者Amit Kumar
相关产品推荐
相关产品推荐

