/ Grid / Immutable Mode
Search results

Immutable Mode in Angular Grid component

21 Dec 2022 / 3 minutes to read

The immutable mode optimizes the Grid re-rendering performance by using the object reference and deep compare concept. When performing the 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.
Copied to clipboard
import { Component, ViewChild } from "@angular/core";
import { ButtonComponent } from "@syncfusion/ej2-angular-buttons";
import { GridComponent } from "@syncfusion/ej2-angular-grids";
import { data } from "./datasource";

@Component({
    selector: 'app-root',
    templateUrl: 'app/app.template.html'
})
export class AppComponent implements OnInit {
  public data: Object[] = [];
  public pageSettings: Object = { pageSize: 50 };
  public immutableStart: number;
  public normalStart: number;
  public primaryKey: number = 0;
  @ViewChild("immutable")
  public immutableGrid: GridComponent;
  @ViewChild("normal")
  public normalGrid: GridComponent;
  @ViewChild("addtop")
  public addtop: ButtonComponent;
  @ViewChild("addbottom")
  public addbottom: ButtonComponent;
  @ViewChild("delete")
  public delete: ButtonComponent;
  @ViewChild("reverse")
  public reverse: ButtonComponent;
  @ViewChild("paging")
  public paging: ButtonComponent;
  public immutableInit: boolean = true;
  public init: boolean = true;

  ngOnInit(): void {
    this.data = data;
  }

  immutableBeforeDataBound(): void {
    this.immutableStart = new Date().getTime();
  }

  immutableDataBound(): void {
    let val: number | string = this.immutableInit ? '' : new Date().getTime() - this.immutableStart;
    document.getElementById("immutableDelete").innerHTML =
      "Immutable rendering Time: " + "<b>" + val + "</b>" + "<b>ms</b>";
    this.immutableStart = 0; this.immutableInit = false;
  }

  normalBeforeDataBound(): void {
    this.normalStart = new Date().getTime();
  }

  normalDataBound(): void {
    let val: number = this.init ? '' : new Date().getTime() - this.normalStart;
    document.getElementById("normalDelete").innerHTML =
      "Normal rendering Time: " + "<b>" + val + "</b>" + "<b>ms</b>";
    this.normalStart = 0; this.init = false;
  }

  addTopEvent(): void {
    let addedRecords: object[] = [
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Chai', 'ProductID': 'Sasquatch Ale', 'CustomerID': 'QUEDE', 'CustomerName': 'Yoshi Tannamuri' },
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Georg Pipps', 'ProductID': 'Valkoinen suklaa', 'CustomerID': 'RATTC', 'CustomerName': 'Martín Sommer' },
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Yoshi Tannamuri', 'ProductID': 'Gula Malacca', 'CustomerID': 'COMMI', 'CustomerName': 'Ann Devon' },
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Palle Ibsen', 'ProductID': 'Rogede sild', 'CustomerID': 'RATTC', 'CustomerName': 'Paula Wilson' },
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Francisco Chang', 'ProductID': 'Mascarpone Fabioli', 'CustomerID': 'ROMEY', 'CustomerName': 'Jose Pavarotti' }
    ];
    var aData = addedRecords.concat(this.immutableGrid.dataSource as object[]);
    this.normalGrid.setProperties({ dataSource: aData });
    this.immutableGrid.setProperties({ dataSource: aData });
  }

  addBottomEvent(): void {
    let addedRecords: object[] = [
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Chai', 'ProductID': 'Sasquatch Ale', 'CustomerID': 'QUEDE', 'CustomerName': 'Yoshi Tannamuri' },
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Georg Pipps', 'ProductID': 'Valkoinen suklaa', 'CustomerID': 'RATTC', 'CustomerName': 'Martín Sommer' },
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Yoshi Tannamuri', 'ProductID': 'Gula Malacca', 'CustomerID': 'COMMI', 'CustomerName': 'Ann Devon' },
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Palle Ibsen', 'ProductID': 'Rogede sild', 'CustomerID': 'RATTC', 'CustomerName': 'Paula Wilson' },
      { 'OrderID': ++this.primaryKey, 'ProductName': 'Francisco Chang', 'ProductID': 'Mascarpone Fabioli', 'CustomerID': 'ROMEY', 'CustomerName': 'Jose Pavarotti' }
    ]
    let aData = addedRecords.concat(this.immutableGrid.dataSource as object[]);
    this.normalGrid.setProperties({ dataSource: aData });
    this.immutableGrid.setProperties({ dataSource: aData });
  }

  deleteEvent(): void {
    (this.immutableGrid.dataSource as object[]).splice(0, 5);
    this.normalGrid.setProperties({ dataSource: this.immutableGrid.dataSource });
    this.immutableGrid.setProperties({ dataSource: this.immutableGrid.dataSource });
  }

  sortEvent(): void {
    let aData: object[] = (this.immutableGrid.dataSource as object[]).reverse();
    this.normalGrid.setProperties({ dataSource: aData });
    this.immutableGrid.setProperties({ dataSource: aData });
  }

  pageEvent(): void {
    let totalPage: number = (this.immutableGrid.dataSource as object[]).length / this.immutableGrid.pageSettings.pageSize;
    let page: number = Math.floor(Math.random() * totalPage) + 1;
    this.normalGrid.setProperties({ pageSettings: { currentPage: page } });
    this.immutableGrid.setProperties({ pageSettings: { currentPage: page } });
  }
}
Copied to clipboard
<table>
    <tbody>
        <tr>
            <td>
                <span id='immutableDelete'></span>
            </td>
        </tr>
        <tr>
            <td>
                <span id='normalDelete'></span>
            </td>
        </tr>
        <tr>
            <td>
                <div>
                    <button #addtop ejs-button class="e-control e-btn e-lib e-info" (click)="addTopEvent()">Add 5 rows
                        at top</button>
                    <button #addbottom ejs-button class="e-control e-btn e-lib e-info" (click)="addBottomEvent()">Add 5
                        rows at bottom</button>
                    <button #delete ejs-button class="e-control e-btn e-lib e-info" (click)="deleteEvent()">Delete 5
                        rows</button>
                    <button #reverse ejs-button class="e-control e-btn e-lib e-info" (click)="sortEvent()">Sort Order
                        ID</button>
                    <button #paging ejs-button class="e-control e-btn e-lib e-info"
                        (click)="pageEvent()">Paging</button>
                </div>
            </td>
        </tr>
        <tr>
            <td>
                <span><b>Immutable Grid</b></span>
                <ejs-grid #immutable [dataSource]='data' height='350' enableImmutableMode="true" allowPaging="true"
                    [pageSettings]="pageSettings" (beforeDataBound)="immutableBeforeDataBound($event)"
                    (dataBound)="immutableDataBound($event)">
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' isPrimaryKey="true" width='120'
                            textAlign='Right'></e-column>
                        <e-column field='ProductName' headerText='Product Name' width='160'></e-column>
                        <e-column field='ProductID' headerText='Product ID' width='120' textAlign='Right'>
                        </e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width='120'></e-column>
                        <e-column field='CustomerName' headerText='Customer Name' width='160'></e-column>
                    </e-columns>
                </ejs-grid>
            </td>
        </tr>
        <tr>
            <td>
                <span><b>Normal Grid</b></span>
                <ejs-grid #normal [dataSource]='data' height='350' allowPaging="true" [pageSettings]="pageSettings"
                    (beforeDataBound)="normalBeforeDataBound($event)" (dataBound)="normalDataBound($event)">
                    <e-columns>
                        <e-column field='OrderID' headerText='Order ID' isPrimaryKey="true" width='120'
                            textAlign='Right'></e-column>
                        <e-column field='ProductName' headerText='Product Name' width='160'></e-column>
                        <e-column field='ProductID' headerText='Product ID' width='120' textAlign='Right'>
                        </e-column>
                        <e-column field='CustomerID' headerText='Customer ID' width='120'></e-column>
                        <e-column field='CustomerName' headerText='Customer Name' width='160'></e-column>
                    </e-columns>
                </ejs-grid>
            </td>
        </tr>
    </tbody>
</table>
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { GridModule, PageService } from '@syncfusion/ej2-angular-grids';
import { AppComponent } from './app.component';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        GridModule
    ],
    declarations: [AppComponent],
    bootstrap: [AppComponent],
    providers: [PageService]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);

Limitations

The following features are not supported in the immutable mode:

  • Frozen rows and columns
  • Row Template
  • Detail Template
  • Hierarchy Grid
  • Column reorder
  • Virtual scroll
  • Infinite scroll
  • Grouping

See also