在数据视图中更新记录时需要处理 angular slickgrid 多次渲染

Need to handle angular slickgrid multiple times rendering while updating a record in dataview

我正在使用 angular slickgrid 来显示我的数据。我持续监控数据。如果服务器端发生任何更改,则该数据需要在应用程序中更新。因此,通过此代码 this.angularGrid.gridService.updateDataGridItem(data); 在 slickgrid 中更新修改后的数据。更新数据时,angular slickgrid 多次完全渲染。我想避免 angular slickgrid 多次渲染。


当前行为

添加或更新记录时,angular slickgrid 呈现多次


预期行为

添加或更新记录时,angular slickgrid 只需要更新特定行数据视图


这里分享我的网格选项供大家参考。

public gridOptions: GridOption = {
    enablePagination: true,
    autoEdit: false,
    enableCellNavigation: true,
    editable: true,
    enableAutoResize: true,
    enableSorting: true,
    enableFiltering: true,
    enableExcelExport: true,
    enableExport: true,
    i18n: this.translateService,
    gridMenu: {
        hideExportExcelCommand: true,
        hideExportCsvCommand: true,
        customItems: [{
            command: "cspfm-excel-export",
            titleKey: "EXPORT_TO_EXCEL",
            iconCssClass: "fa fa-file-excel-o",
            action: (event, callbackArgs) => {
                this.excelExport(event, callbackArgs)
            }
        }, {
            command: "cspfm-csv-export",
            titleKey: "EXPORT_TO_CSV",
            iconCssClass: "fa fa-download",
            action: (event, callbackArgs) => {
                this.excelExport(event, callbackArgs)
            }
        }],
    },
    enableAutoTooltip: true,
    autoTooltipOptions: {
        enableForCells: true,
        enableForHeaderCells: true,
        maxToolTipLength: 1000
    },
    headerMenu: {
        hideColumnHideCommand: true
    },
    autoResize: {
        containerId: this.gridContainerId,
        calculateAvailableSizeBy: 'container'
    },
    exportOptions: {
        exportWithFormatter: true
    },
    excelExportOptions: {
        exportWithFormatter: true,
    },
    enableTranslate: true,
    presets: {
        sorters: [{ columnId: this.tableColumnInfo['pfm138993_institutename']['prop'], direction: 'ASC' }],
    },
    enableAsyncPostRender: true, // for the Angular PostRenderer, don't forget to enable it
    asyncPostRenderDelay: 0,    // also make sure to remove any delay to render it
    params: {
        angularUtilService: this.angularUtilService // provide the service to all at once (Editor, Filter, AsyncPostRender)
    },
    checkboxSelector: {
        // you can toggle these 2 properties to show the "select all" checkbox in different location
        hideInFilterHeaderRow: false,
    },
    rowSelectionOptions: {
        // True (Single Selection), False (Multiple Selections)
        selectActiveRow: false,
    },
    enableCheckboxSelector: true,
    enableRowSelection: true
};

软件版本

Angular : 7.3.5

Angular-Slickgrid:2.19.0

打字稿:3.1.6

操作系统:Windows10

节点:10.16.3

NPM:6.9.0

首先,您使用的是 updateDataGridItem() 这是一种旧的 已弃用 方法,您应该会在浏览器中收到控制台警告,告诉您使用较新的 updateItem() 方法。

其次,您提供了网格选项,但这与网格渲染 and/or 更新无关。您应该在问题中包含的是更新项目部分的完整代码。因为你没有包括那部分,我只能假设你只是在做那个项目更新,没有别的!?!但这只是一个假设...

如果您使用较新的 updateItem() 方法,您可以在第二个参数中提供一些额外的选项,其中之一是 highlightRow(默认启用),它可能会重新渲染网格几次,你可以像这样禁用它

this.angularGrid.gridService.updateItem(data, { highlightRow: false });

// OR update by item id
// this.angularGrid.gridService.updateItemById(data.id, data, { highlightRow: false });

要查看其他选项,您可以查看此 line

上设置的默认值

如果仍然多次渲染网格,您可以尝试自己直接使用 SlickGrid DataView(这基本上是 Grid Service 所做的,该服务是提供帮助来轻松处理 DataView)。

// update the item in the DataView
this.angularGrid.dataView.updateItem(itemId, item);

// refresh (render) the row in the grid (else you will still see the previous value)
const rowNumber = this.angularGrid.dataView.getRowById(itemId);
this.angularGrid.slickGrid.updateRow(rowNumber);

如果在所有这些结束时您仍然有多个渲染,那么您将不得不对 SlickGrid(核心库)代码进行故障排除并尝试找出何时以及如何重新渲染网格...祝您好运有了这个,我不会做那个任务,但如果你发现了一些东西,那么为这个库做贡献会很有帮助。

因此希望禁用 highlightRow 将有助于减少网格渲染执行。旁注,默认是当前突出显示,但我决定在下一个主要版本中默认禁用它,因为它在更新时有太多副作用(但是插入新行仍会突出显示)。


旁注,如果您想同时更新多个项目,出于性能原因,您应该使用 DataView Transactions(beginUpdateendUpdate)并且只呈现一次。我忘了在网格服务中利用它,所以我创建了这个 PR 来解决多个 (inserts/updates/upserts),基本上直接使用 DataView 时看起来像这样(这也是它更容易的另一个原因使用网格服务助手)

const dataView = this.angularGrid.dataView;

dataView.beginUpdate();

dataView.updateItem(itemId1, item1);
dataView.updateItem(itemId2, item2);
dataView.updateItem(itemId3, item3);

dataView.endUpdate();