Nelson Gnanaraj
Nelson Gnanaraj

Reputation: 176

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

I am using angular slickgrid to show my data. I monitoring the data continuously. If any changes happened in server side, that data need to update in application. So that modified data updated in slickgrid by this code this.angularGrid.gridService.updateDataGridItem(data);. While updating data, the angular slickgrid fully rendered for multiple times. I want avoid angular slickgrid multiple times rendering.


Current behavior

While adding or updating a record, angular slickgrid renders multiple time


Expecting behavior

While adding or updating a record, angular slickgrid needs to update the particular row dataview only


Here i shared my gridoptions for your reference.

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
};

Software Version

Angular : 7.3.5

Angular-Slickgrid : 2.19.0

TypeScript : 3.1.6

Operating System : Windows 10

Node : 10.16.3

NPM : 6.9.0

Upvotes: 1

Views: 834

Answers (1)

ghiscoding
ghiscoding

Reputation: 13194

First of, you're using updateDataGridItem() which is an old and deprecated method, you're supposed to get console warning in your browser telling you to use the newer updateItem() method.

Second, you provided your Grid Options but that has nothing to do with grid rendering and/or update. What you should have included in your question is the entire code for the update item part. Since you didn't include that part, I can only assume that you're doing just that item update and nothing else!?! but that is just an assumption...

If you use the newer updateItem() method, you can provide some extra options in the 2nd argument, one of which is the highlightRow (which is enabled by default) which will probably re-render the grid couple times, you can disable it like so

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

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

To see the other options, you can take a look at the defaults set on this line

If that still renders the grid multiple times, you can try to use directly the SlickGrid DataView yourself (which basically is what the Grid Service does, that Service is to provide helpers to easily deal with the 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);

If at the end of all that you still have multiple renders, then you'll have to troubleshoot the SlickGrid (core lib) code and try to find when and how the grid gets re-render... good luck with that, I will not do that task, but if you find something it would be helpful to contribute to the lib.

So hopefully disabling the highlightRow will help in getting less grid rendering execution. A side note, the default is to currently highlight but I decided to disable it by default in the next major version since it has too many side effect when updating (however inserting a new row will still highlight).


Side note, if you want to update multiple items at the same time, you should use the DataView Transactions (beginUpdate and endUpdate) for performance reason and also to render only once. I forgot to take advantage of that in the Grid Service, so I created this PR to address multiple (inserts/updates/upserts), basically that would look like this when using the DataView directly (yet another reason why it's easier to use the Grid Service helper)

const dataView = this.angularGrid.dataView;

dataView.beginUpdate();

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

dataView.endUpdate();

Upvotes: 1

Related Questions