Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ag-grid resizing columns taking too long to respond when used with an modal overlay in ember.js

We have faced an issue while using ag-grid with a modal overlay. We have a feature where we have to show a modal box to show extended items when a row is clicked. Now once this modal box is dismissed and then the user attempts to resize the columns of ag-grid, it takes around 10-15 sec to happen against the initial real-time resizing. Also, the data in this modal box is filled dynamically, here is the code for the same:-

for (const data of pop_data) {
    if (count == pop_data.length-1) {
        bn += data;
    }
    else {
        bn += data+' </br>';
    }
    count++
}
jQuery(".ember-modal-dialog").addClass("data-show-more")
jQuery(".ember-modal-dialog").html(bn)

To show/hide this modal, we use the ember.js controller variable:

{{#if isShowingModal}}
  {{#modal-dialog
      onClose=(action "toggleModal")
      targetAttachment="center"
      translucentOverlay=true
  }}
    {{modalMessage}}
  {{/modal-dialog}}
{{/if}}

Here is the ag-grid definition:-

let columnDefs = [
      {
        headerName: "A", field: "email",
        width: 300
      },
      {
        headerName: "B", field: "enabled",
        width: 93
      },
      {
        headerName: "C", field: "f_l",
        width: 200
      },
      { headerName: "D", field: "mp", hide: !assign_features.includes("mp"), width:105 },
      { headerName: "OH", field: "oh", hide: !assign_features.includes("oh"), width:130},
      { headerName: "R", field: "vsr", hide: !assign_features.includes("vsr") },
      { headerName: "EC", field: "ir", hide: !assign_features.includes("ir") },
      { headerName: "UR", field: "ir", hide: !assign_features.includes("vsr") },
      { headerName: "MU", field: "mu", hide: !assign_features.includes("mu") },
      { headerName: "MC", field: "mc", hide: !assign_features.includes("mc")},
      {
        headerName: "CP",
        field: 'buyers',
        cellRenderer: 'modalbuyerRenderer',
        cellClass: 'cell-wrap-text',
        autoHeight: 'true',
        width: 400,
      }
    ];

    let gridOptions = {
      columnDefs: columnDefs,
      components: {
      'modalbuyerRenderer': mbr
      },
      defaultColDef: {
        sortable: true,
        resizable: true,
        width: 130,
        sortingOrder: ['asc','desc'],
      },
      onRowClicked: function(event) {
            onRowClickedEvent(event);
        }
      },
    };
like image 465
Rishabh Shah Avatar asked Jan 17 '20 07:01

Rishabh Shah


1 Answers

Without seeing a working plunkr/codepen I think the solution to your issue could lie within the built in gridOptions API. Recently I have just ran into a very similar issue (not with resizing but with re-rendering single cells after interaction) and using api.setRowData and setColumnDefs resolved my issue. The code below is based in angularJS and simplified a lot to give a general idea on what you might try. I hope this helps - it resolved my similar issue.

First the initiation of the gridOptions:

$scope.gridOptions = {
    // we are using angular in the templates
    defaultColDef: {
        filter: true,
        sortable: true,
        resizable: true,
    },
    ...,
    onCellClicked: function(event, $event) {
        //
    }
    onGridReady: () => {
        //setup first yourColumnDefs and yourGridData
        //now use the api to set the columnDefs and rowData
        $scope.gridOptions.api.setColumnDefs(yourColumnDefs);
        $scope.gridOptions.api.setRowData(yourGridData);
    },
    onFirstDataRendered: function() {
        //
    }
};

Then the interaction happens (let's say a deletion of one of the rows). An important note is that $scope.gridLoaded is a boolean that hides/shows the DOM element which is the ag-grid itself. So basically at the beginning of the interaction the element disappears briefly (and a loader appears) and when the interaction is finished the table is re-rendered (and the loader disappears). For very large lists and frequent interactions, this re-rendering is obviously not the best option, though for these lists ag-grid (without pagination) itself might not yield the best performance.

$scope.delete = (params) => {
    // safeApply() is a function which forces update immediately outside of the digest cycle
    // gridLoaded is set false here
    $rootScope.safeApply( () => { $scope.gridLoaded = false; });

    let updatePromise = ...

    $.when(updatePromise).then( () => {
        $rootScope.safeApply(() => {
            $scope.gridLoaded = true;
            $scope.gridOptions.api.setRowData(yourGridData_updated);
            // given that your problem is with resizing it might worth considering re-running the $scope.gridOptions.api.setColumnDefs(yourColumnDefs) function as well
        })
    }, (err) => {
        console.warn(err);
    })
}
like image 154
Andrew Adam Avatar answered Sep 23 '22 13:09

Andrew Adam