All Components

Persisting the Expanded State

The TreeView enables you to define and persist the expanded state of its nodes when the component is re-rendered.

Basics

The TreeView exposes the following options to control the expand state:

  • isExpanded (function)—Determines if a given node is expanded.
  • collapse (event)—Fired when a given node is about to be collapsed.
  • expand (event)—Fired when a given node is about to be expanded.
import { Component } from '@angular/core';
import { of } from 'rxjs/observable/of';

@Component({
    selector: 'my-app',
    template: `
     <kendo-treeview
         [nodes]="data"
         [children]="children"
         [hasChildren]="hasChildren"
         textField="text"

         [isExpanded]="isExpanded"
         (collapse)="handleCollapse($event)"
         (expand)="handleExpand($event)"
     >
     </kendo-treeview>
 `
})
export class AppComponent {
    public data: any[] = [
        {
            text: 'Furniture', items: [
                { text: 'Tables & Chairs' },
                { text: 'Sofas' },
                { text: 'Occasional Furniture' }
            ]
        },
        {
            text: 'Decor', items: [
                { text: 'Bed Linen' },
                { text: 'Curtains & Blinds' },
                { text: 'Carpets' }
            ]
        }
    ];

    /**
     * The field that holds the keys of the expanded nodes.
     */
    public keys: string[] = [];

    /**
     * A function that checks whether a given node index exists in the expanded keys collection.
     * If the index can be found, the node is marked as expanded.
     */
    public isExpanded = (dataItem: any, index: string) => {
        return this.keys.indexOf(index) > -1;
    }

    /**
     * A `collapse` event handler that will remove the node hierarchical index
     * from the collection, collapsing its children.
     */
    public handleCollapse(node) {
        this.keys = this.keys.filter(k => k !== node.index);
    }

    /**
     * An `expand` event handler that will add the node hierarchical index
     * to the collection, expanding the its children.
     */
    public handleExpand(node) {
        this.keys = this.keys.concat(node.index);
    }

    public children = (dataitem: any): any[] => of(dataitem.items);
    public hasChildren = (dataitem: any): boolean => !!dataitem.items;
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TreeViewModule } from '@progress/kendo-angular-treeview';

import { AppComponent } from './app.component';

@NgModule({
  bootstrap:    [ AppComponent ],
  declarations: [ AppComponent ],
  imports:      [ BrowserModule, BrowserAnimationsModule, TreeViewModule]
})
export class AppModule { }
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Built-in Directives

To persist the expanded state of the TreeView, either:

Using the Built-In Directive

By default, the built-in ExpandDirective persists the expanded items based on their hierarchical index.

The TreeView renders the expand icons only after the children and hasChildren functions are defined.

import { Component } from '@angular/core';

import { of } from 'rxjs/observable/of';

@Component({
    selector: 'my-app',
    template: `
        <div class="example-config">
            Expanded keys: {{expandedKeys.join(",")}}
        </div>
        <kendo-treeview
            [nodes]="data"
            textField="text"
            [hasChildren]="hasChildren"
            [children]="fetchChildren"

            kendoTreeViewExpandable
            [(expandedKeys)]="expandedKeys"
        >
        </kendo-treeview>
  `
})
export class AppComponent {
    public expandedKeys: any[] = ['1'];

    public data: any[] = [
        {
            text: 'Furniture', items: [
                { text: 'Tables & Chairs' },
                { text: 'Sofas' },
                { text: 'Occasional Furniture' }
            ]
        },
        {
            text: 'Decor', items: [
                { text: 'Bed Linen' },
                { text: 'Curtains & Blinds' },
                { text: 'Carpets' }
            ]
        }
    ];

    public hasChildren = (item: any) => item.items && item.items.length > 0;
    public fetchChildren = (item: any) => of(item.items);
}

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TreeViewModule } from '@progress/kendo-angular-treeview';

import { AppComponent } from './app.component';

@NgModule({
  bootstrap:    [ AppComponent ],
  declarations: [ AppComponent ],
  imports:      [ BrowserModule, BrowserAnimationsModule, TreeViewModule]
})
export class AppModule { }

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Setting an Item Field

You can also persist the expanded state of the TreeView by item field—for example, the id field.

import { Component } from '@angular/core';
import { of } from 'rxjs/observable/of';

@Component({
    selector: 'my-app',
    template: `
        <div class="example-config">
            Expanded keys: {{expandedKeys.join(",")}}
        </div>
        <kendo-treeview
            [nodes]="data"
            textField="text"
            [hasChildren]="hasChildren"
            [children]="fetchChildren"

            kendoTreeViewExpandable
            [expandBy]="'text'"
            [(expandedKeys)]="expandedKeys"
        >
        </kendo-treeview>
  `
})
export class AppComponent {
    public expandedKeys: any[] = ['Furniture'];

    public data: any[] = [
        {
            text: 'Furniture', items: [
                { text: 'Tables & Chairs' },
                { text: 'Sofas' },
                { text: 'Occasional Furniture' }
            ]
        },
        {
            text: 'Decor', items: [
                { text: 'Bed Linen' },
                { text: 'Curtains & Blinds' },
                { text: 'Carpets' }
            ]
        }
    ];

    public hasChildren = (item: any) => item.items && item.items.length > 0;
    public fetchChildren = (item: any) => of(item.items);
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TreeViewModule } from '@progress/kendo-angular-treeview';

import { AppComponent } from './app.component';

@NgModule({
  bootstrap:    [ AppComponent ],
  declarations: [ AppComponent ],
  imports:      [ BrowserModule, BrowserAnimationsModule, TreeViewModule]
})
export class AppModule { }
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
In this article