DevExtreme v26.1 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

Angular Tree List - Load Data on Demand

The TreeList can load a remote dataset dynamically as a user expands nodes. The dataset must have a plain structure.

Backend API
<dx-tree-list id="treelist" [dataSource]="dataSource" [showBorders]="true" [remoteOperations]="{ filtering: true }" keyExpr="id" parentIdExpr="parentId" hasItemsExpr="hasItems" rootValue="" > <dxi-tree-list-column dataField="name"></dxi-tree-list-column> <dxi-tree-list-column dataField="size" [width]="100" [customizeText]="customizeSizeText" ></dxi-tree-list-column> <dxi-tree-list-column dataField="createdDate" dataType="date" [width]="150" ></dxi-tree-list-column> <dxi-tree-list-column dataField="modifiedDate" dataType="date" [width]="150" ></dxi-tree-list-column> </dx-tree-list>
import { bootstrapApplication } from '@angular/platform-browser'; import { Component, enableProdMode, provideZoneChangeDetection } from '@angular/core'; import { HttpClient, HttpParams, provideHttpClient, withFetch } from '@angular/common/http'; import { lastValueFrom } from 'rxjs'; import { DxTreeListModule } from 'devextreme-angular'; import { DataSource } from 'devextreme-angular/common/data'; if (!/localhost/.test(document.location.host)) { enableProdMode(); } @Component({ selector: 'demo-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], imports: [ DxTreeListModule, ], }) export class AppComponent { dataSource: DataSource; constructor(http: HttpClient) { this.dataSource = new DataSource({ load(loadOptions) { let params = new HttpParams(); if (loadOptions.parentIds) { loadOptions.parentIds.forEach((id) => { params = params.append('parentIds', id); }); } return lastValueFrom( http.get('https://js.devexpress.com/Demos/NetCore/api/treeListData', { params }), ); }, }); } customizeSizeText = ({ value }) => (value === null ? '' : `${Math.ceil(value / 1024)} KB`); } bootstrapApplication(AppComponent, { providers: [ provideZoneChangeDetection({ eventCoalescing: true, runCoalescing: true }), provideHttpClient(withFetch()), ], });
::ng-deep #treelist { max-height: 440px; }
<!DOCTYPE html> <html lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/26.1.5/css/dx.light.css" /> </head> <body class="dx-viewport"> <div class="demo-container"> <demo-app>Loading...</demo-app> </div> <script src="https://cdn.jsdelivr.net/npm/zone.js@0.16.2/bundles/zone.umd.js"></script> <script src="./bundle.js" type="module"></script> </body> </html>

This feature requires client- and server-side configurations. To configure the client-side part, do the following:

  1. Send an expanded node's ID to the server
    For this, implement the CustomStore's load function. In this demo, we do it in the dataSource configuration object.

  2. Delegate filtering to the server
    Set the remoteOperations.filtering property to true.

  3. Specify the data field that defines whether the node has children
    Use the hasItemsExpr property to set this data field.

Server-side implementation is available in the ASP.NET Core and ASP.NET MVC versions of this demo under the TreeListDataController.cs tab.

This demo uses a simple data bind technique that is useful for data display purposes only. When a user clicks a node, TreeList receives a JSON object from the server, which is based on the parentIds property value. This technique does not support the built-in data process operations in TreeList on the server.

If your project needs to process data, do one of the following instead: