简版: 在Ag-grid上使用一个无限行模型,我需要一种方法来设置过滤器和排序模型,在第一个模型之后。getRows()
请求(我不能在第一个请求完成之前设置列定义)。有谁有办法在不触发更多getRows的情况下做到这一点?
完整的上下文:我正在为一个Angular应用使用Ag-grid与无限行模型。我们正在使用它来查看大型平面数据集的过滤器排序。网格正确地处理它,以便当用户在网格上更改过滤器或排序时,数据源中的getRows请求将以新的filtersort模型触发。
我还需要在应用程序上有路由。如果用户打开某个数据集的网格,添加了一个过滤器排序,这应该反映在url中。我们的想法是,用户可以分享该页面的链接,如果在新窗口中打开,该页面将自动加载第一个用户正在查看的数据。我把路由也弄好了。值得注意的是,当加载一个新的网格时,我们永远不会知道列的定义到底是什么。
问题:当第二个用户打开链接时,grid会加载并向服务器发送一个带有正确过滤器的请求。然而,网格的排序过滤器状态并没有反映出这一点,这很公平,因为我们刚刚初始化了一个新的网格,而且还没有设置排序过滤器模型,但它需要被设置,否则当用户滚动时,原来的过滤器将不再被应用。然而,我在实际设置排序过滤器模型时遇到了麻烦,同时也在努力避免触发对服务器的额外请求。gridApi.setSortModel(sortModel)
和 gridApi.setFilterModel(filterModel)
以及设置一个全局变量来告诉网格在设置模型后不要再要求行。
但这并不奏效。getRows()请求再次被触发,但由于某些原因,过滤器和排序模型仍然是空的。下面是我使用的数据源的大概情况。
createDatasource(grid): IDatasource {
return {
getRows: params => {
if (grid.ignoreRequest) {
grid.ignoreRequest = false;
params.failCallback();
return;
} else {
const query = generateQuery(params);
this.api.getData(query).then(response => {
if (!grid.columnDefs.length) {
const sortModel = generateSortModel(query);
grid.ignoreRequest = true;
grid.columnDefs = grid.generateColumnDefs(response[0]);
grid.gridApi.setSortModel(sortModel);
}
params.successCallback(response, response.length);
} handleErr);
}
}
};
}
(注意,上面的代码略微简化了,但结构是一样的)。
按照上面的配置,网格会加载一次数据,正确创建列定义,然后再打一次getRows()请求,这样就能正确处理好 ignoreRequest
参数,但是排序模型没有正确设置。另外,尽管第一个请求正确地工作并设置了行,但在第二个请求被忽略后,网格中没有行数据,只有列定义。
我在git hub上发现有人问了类似的问题,但是这些例子并没有帮助我,因为我需要在第一个请求之后而不是之前设置列定义。https:/github.comag-gridag-gridissues1785。
希望能得到任何帮助。
问题中的代码有2个问题。
列定义需要使用grid api来设置,而不是仅仅设置一个变量。在网格上设置变量意味着列会正确显示,但除非调用gridApi.setColumnDefs(columnDefs),否则后续调用设置排序或过滤模型将无法工作。一旦做了这个改变,排序模型就会正确反映出来。
在我看到的其他例子中。failCallback()
的方法,当我们想忽略这个请求时,就会使用这个方法。对我来说,这只是将行设置为空白,也许在其他解决方案发布后,该方法已经更新为这样做了。而应该改成 successCallback。这个方法需要行数据,所以在设置filtersort模型之前,行数据需要以某种方式持久化。
这里是一个更新的(基本)版本。getRows()
功能。
createDatasource(grid): IDatasource {
return {
getRows: params => {
if (_.get(grid, 'ignoreRequestount', 0) > 0) {
grid.ignoreRequestCount--;
params.successCallback(grid.rowData);
} else {
const query = generateQuery(params);
this.api.getData(query).then(response => {
grid.ignoreRequestCount = 0;
const sortModel = this.ODataQueryToSortModel(query);
const filterModel = this.ODataQueryToFilterModel(query);
grid.columnDefs = gridTab.generateColumnDefs(response[0]);
grid.gridApi.setColumnDefs(grid.columnDefs);
if (_.keys(filterModel).length) {
grid.ignoreRequestCount += 1;
grid.gridApi.setFilterModel(filterModel);
}
if (sortModel.length) {
grid.ignoreRequestCount += 1;
grid.gridApi.setSortModel(sortModel);
}
params.successCallback(response, response.length);
} handleErr);
}
}
};
}
同样,这也是简化的,但基本上涵盖了它。我不得不调整检查是否应该忽略请求,因为在某些情况下,filterModel和sortModel可能被设置,这将导致多个触发。这是一个有点黑客的方法,但也只能这样了,除非有人有更好的解决方案......