Tree Grid Remote Data Operations Overview

The Ignite UI for Angular Tree Grid supports remote data operations such as remote virtualization, remote sorting, remote filtering and others. This allows the developer to perform these tasks on a server, retrieve the data that is produced and display it in the Tree Grid.

Demo


By default, the Tree Grid uses its own logic for performing data operations. You can perform these tasks remotely and feed the resulting data to the Tree Grid by taking advantage of certain inputs and events, which are exposed by the Tree Grid.

Remote Filtering

To provide remote filtering, you need to subscribe to the filteringExpressionsTreeChange output so that you make the appropriate request based on the arguments received. Let's use a flat collection as a data source for our Tree Grid by providing a primaryKey and a foreignKey.

We will also take advantage of the rxjs debounceTime function, which emits a value from the source Observable only after a particular time span has passed without another source emission. This way the remote operation will be triggered only when the specified amount of time has passed without the user interrupting it.

const DEBOUNCE_TIME = 300;
...
public ngAfterViewInit() {
    ...
    this.treeGrid.filteringExpressionsTreeChange.pipe(
        debounceTime(DEBOUNCE_TIME),
        takeUntil(this.destroy$)
    ).subscribe(() => {
        this.processData();
    });
}

When remote filtering is provided, usually we do not need the built-in filtering of the Tree Grid. We can disable it by setting the filterStrategy input of the Tree Grid to the NoopFilteringStrategy instance.

<!-- tree-grid-remote-filtering-sample.html -->

<igx-tree-grid #treeGrid [data]="remoteData | async" primaryKey="ID" foreignKey="ParentID" [autoGenerate]="false" width="100%" height="450px"
               [autoGenerate]="false"
               [filterStrategy]="noopFilterStrategy"
               [allowFiltering]="true">
    <igx-column [field]="'Name'" dataType="string"></igx-column>
    <igx-column [field]="'Title'" dataType="string"></igx-column>
    <igx-column [field]="'Age'" dataType="number"></igx-column>
    ...
</igx-tree-grid>
// tree-grid-remote-filtering-sample.ts

public noopFilterStrategy = NoopFilteringStrategy.instance();

public processData() {
    this.treeGrid.isLoading = true;

    const filteringExpr = this.treeGrid.filteringExpressionsTree;

    this._remoteService.getData(filteringExpr, () => {
        this.treeGrid.isLoading = false;
    });
}

The remote filtering will have to be performed over the flat collection directly. We will also have to include all the parents for any record that matches the filtering condition regardless of whether or not the parents match the filtering (we do this to keep the hierarchy intact). The result can be seen below:

Note

When remote data is requested, the filtering operation is case-sensitive.

Remote Filtering Demo

You can see the result of the code from above at the beginning of this article in the Demo section.

Unique Column Values Strategy

The list items inside the Excel Style Filtering dialog represent the unique values for the respective column. The Tree Grid generates these values based on its data source by default. In case of remote filtering, the grid data does not contain all the data from the server. In order to provide the unique values manually and load them on demand, we can take advantage of the Tree Grid's uniqueColumnValuesStrategy input. This input is actually a method that provides three arguments:

  • column - The respective column instance.
  • filteringExpressionsTree - The filtering expressions tree, which is reduced based on the respective column.
  • done - Callback that should be called with the newly generated column values when they are retrieved from the server.

The developer can manually generate the necessary unique column values based on the information, that is provided by the column and the filteringExpressionsTree arguments and then invoke the done callback.

Note

When the uniqueColumnValuesStrategy input is provided, the default unique values generating process in the excel style filtering will not be used.

<igx-tree-grid #treeGrid [data]="data" [filterMode]="'excelStyleFilter'" [uniqueColumnValuesStrategy]="columnValuesStrategy">
    ...
</igx-tree-grid>
public columnValuesStrategy = (column: IgxColumnComponent,
                               columnExprTree: IFilteringExpressionsTree,
                               done: (uniqueValues: any[]) => void) => {
    // Get specific column data.
    this.remoteValuesService.getColumnData(column, columnExprTree, uniqueValues => done(uniqueValues));
}

Unique Column Values Strategy Demo


In order to provide a custom loading template for the excel style filtering, we can use the igxExcelStyleLoading directive:

<igx-tree-grid [data]="data" [filterMode]="'excelStyleFilter'" [uniqueColumnValuesStrategy]="columnValuesStrategy">
    ...
    <ng-template igxExcelStyleLoading>
        Loading ...
    </ng-template>
</igx-tree-grid>

Remote Paging

In this sample we will demonstrate how to display a certain number of root records per page no matter how many child records they have. In order to cancel the built-in Tree Grid paging algorithm, which displays a certain number of records no matter their level (root or child), we have to set the perPage property to Number.MAX_SAFE_INTEGER.

<igx-tree-grid #treeGrid ...
               [paging]="true" [perPage]="maxPerPage">
public maxPerPage = Number.MAX_SAFE_INTEGER;

We need to create a custom pager template to get the data only for the requested page and to pass the correct skip and top parameters to the remote service according to the selected page and items perPage. We are going to use the <igx-paginator> in order to ease our configuration.

<ng-template #customPager let-api>
    <igx-paginator #paginator
        [totalRecords]="totalCount"
        [(perPage)]="perPage"
        [selectLabel]="'Records per page:'"
        [selectOptions]="selectOptions"
        [displayDensity]="grid1.displayDensity"
        (pageChange)="paginate($event)">
    </igx-paginator>
</ng-template>
public paginate(page: number) {
    this.page = page;
    const skip = this.page * this.perPage;
    const top = this.perPage;

    this.remoteService.getData(skip, top);
}

The last step will be to declare our template for the gird.

<igx-tree-grid #treeGrid [data]="data | async" childDataKey="Content" expansionDepth="0" width="100%"
                [paging]="true" [perPage]="maxPerPage" [paginationTemplate]="customPager">
    <igx-column field="Name">
        <ng-template igxCell let-cell="cell" let-val>
            <igx-icon *ngIf="cell.rowData.Type === 'File folder'" fontSet="material" class="typeIcon">folder</igx-icon>
            <igx-icon *ngIf="cell.rowData.Type === 'JPG File'" fontSet="material" class="typeIcon">photo</igx-icon>
            {{val}}
        </ng-template>
    </igx-column>
    <igx-column field="Type"></igx-column>
    <igx-column field="Size" dataType="number" [formatter]="formatSize"></igx-column>
</igx-tree-grid>

After all the changes above, the following result will be achieved.

Remote Paging Demo


API References

Additional Resources

Our community is active and always welcoming to new ideas.