Immutable mode in EJ2 TypeScript Treegrid control

16 Sep 202315 minutes to read

The immutable mode optimizes the Tree Grid re-rendering performance by using the object reference and deep compare concept. When performing the Tree Grid actions, it will only re-render the modified or newly added rows and prevent the re-rendering of the unchanged rows.

To enable this feature, you have to set the enableImmutableMode property as true.

  • This feature uses the primary key value for data comparison. So, you need to provide the isPrimaryKey column.
import { TreeGrid, Page, Edit } from '@syncfusion/ej2-treegrid';
import { sampleData2, dataSource1, sampleData } from './datasource.ts';

TreeGrid.Inject(Page, Edit);

let immutableStart: any;
let normalStart: any;
let immutableInit = true;
let init = true;
if(sampleData2.length == 0){
  dataSource1();
}

    let immutableGrid: TreeGrid = new TreeGrid(
        {
            dataSource: sampleData2,
            childMapping: 'subtasks',
            height: 350,
            allowPaging: true,
            pageSettings: {pageSize: 50},
            treeColumnIndex: 1,
            enableImmutableMode: true,
            selectionSettings: { type: "Multiple" },
            editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' },
            beforeDataBound: () => {
                immutableStart = new Date().getTime();
            },
            dataBound: ()=> {
            let val = immutableInit ? '' : new Date().getTime() - immutableStart;
            document.getElementById('immutableDelete').innerHTML = 'Immutable rendering Time: ' + "<b>" + val + "</b>" + '<b>ms</b>';
            immutableStart = 0; immutableInit = false;
            },
            columns: [
                { field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, width: 70, textAlign: 'Right' },
                { field: 'taskName', headerText: 'Task Name', width: 200, textAlign: 'Left' },
                { field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', type: 'date', format: 'yMd' },
                { field: 'endDate', headerText: 'End Date', width: 90, textAlign: 'Right', type: 'date', format: 'yMd' },
                { field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' },
                { field: 'progress', headerText: 'Progress', width: 80, textAlign: 'Right' },
                { field: 'priority', headerText: 'Priority', width: 90 }
            ]
        });
    immutableGrid.appendTo('#immutable');
document.getElementById('delete').addEventListener('click', function(e) {
  normalGrid.selectRows([0, 2, 4]);
  immutableGrid.selectRows([0, 2, 4]);
  normalGrid.deleteRecord();
  immutableGrid.deleteRecord();
});
document.getElementById('addtop').addEventListener('click', function(e) {
  normalGrid.addRecord(sampleData[0], 0, "Top");
  immutableGrid.addRecord(sampleData[0], 0, "Top");
});
document.getElementById('addbottom').addEventListener('click', function(e) {
  normalGrid.addRecord(sampleData[0], 0, "Bottom");
  immutableGrid.addRecord(sampleData[0], 0, "Bottom");
});
document.getElementById('reverse').addEventListener('click', function(e) {
  let aData = (immutableGrid.dataSource as any).reverse();
  normalGrid.setProperties({ dataSource: aData });
  immutableGrid.setProperties({ dataSource: aData });
});
document.getElementById('paging').addEventListener('click', function(e) {
  let page = normalGrid.pageSettings.currentPage + 1;
  normalGrid.goToPage(page);
  immutableGrid.goToPage(page);
});
let normalGrid: TreeGrid = new TreeGrid({
    dataSource: sampleData2,
    childMapping: 'subtasks',
    height: 350,
    allowPaging: true,
    selectionSettings: { type: "Multiple" },
    editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Cell' },
    pageSettings: {pageSize: 50},
    treeColumnIndex: 1,
    beforeDataBound: () => {
        normalStart = new Date().getTime();
    },
    dataBound: ()=> {
        let val = init ? '' : new Date().getTime() - normalStart;
        document.getElementById('normalDelete').innerHTML = 'Normal rendering Time: ' + "<b>" + val + "</b>" + '<b>ms</b>';
        normalStart = 0; init = false;
    },
    columns: [
                { field: 'taskID', headerText: 'Task ID',  isPrimaryKey: true, width: 70, textAlign: 'Right' },
                { field: 'taskName', headerText: 'Task Name', width: 200, textAlign: 'Left' },
                { field: 'startDate', headerText: 'Start Date', width: 90, textAlign: 'Right', type: 'date', format: 'yMd' },
                { field: 'endDate', headerText: 'End Date', width: 90, textAlign: 'Right', type: 'date', format: 'yMd' },
                { field: 'duration', headerText: 'Duration', width: 80, textAlign: 'Right' },
                { field: 'progress', headerText: 'Progress', width: 80, textAlign: 'Right' },
                { field: 'priority', headerText: 'Priority', width: 90 }
    ]
});
normalGrid.appendTo('#normal');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Tree Grid</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Tree Grid Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
     <!-- Syncfusion Essential JS 2 Styles -->
    <link rel="stylesheet" href="https://cdn.syncfusion.com/ej2/material.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<style>
    .immutablegrid,
    .normalgrid {
        pointer-events: none;
    }
</style>
<body>
   <div id='loader'>Loading....</div>
    <div id='container'>
        <table>
            <tbody>
                <tr>
                    <td>
                        <span id='immutableDelete'></span>
                    </td>
                </tr>
                <tr>
                    <td>
                        <span id='normalDelete'></span>
                    </td>
                </tr>
                <tr>
                    <td>
                        <div>
                            <button id="addtop" class="e-control e-btn e-lib e-info">Add row at top</button>
                            <button id="addbottom" class="e-control e-btn e-lib e-info">Add row at bottom</button>
                            <button id="delete" class="e-control e-btn e-lib e-info">Delete 5 rows</button>
                            <button id="reverse" class="e-control e-btn e-lib e-info">Sort Task ID</button>
                            <button id="paging" class="e-control e-btn e-lib e-info">Paging</button>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>
                        <span><b>Immutable Tree Grid</b></span>
                        <div id='immutable' class="immutablegrid"></div>
                    </td>
                    <td>
                        <span><b>Normal Tree Grid</b></span>
                        <div id='normal' class="normalgrid"></div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>  
</body>
</html>

Limitations

The following features are not supported in the immutable mode:

  • Frozen rows and columns
  • Row Template
  • Detail Template
  • Column reorder
  • Virtualization

You can refer to our JavaScript Tree Grid feature tour page for its groundbreaking feature representations. You can also explore our JavaScript Tree Grid example JavaScript Tree Grid example to knows how to present and manipulate data.