Guides
Guides

2-way binding to state

You can control the tree state using 2-way binding.
The state includes the following:

  • expandedNodeIds - dictionary of node IDs to booleans
  • selectedLeafNodeIds - dictionary of node IDs to booleans
  • activeNodeIds - dictionary of node IDs to booleans
  • hiddenNodeIds - dictionary of node IDs to booleans
  • focusedNodeId - node ID

You can change the state reference and the tree will respond automatically, and also access the tree state at any time, as it is always updated via the 2-way binding.

Example:

import { Component } from '@angular/core';
import { ITreeState } from 'angular-tree-component';

@Component({
  selector: 'app-saverestore',
  template: `
    <tree-root [(state)]="state" [nodes]="nodes"></tree-root>
    <button (click)="collapseAll()">collapse all</button>
    <button (click)="hideFolders()">hide folders</button>
  `,
  styles: []
})
export class MyComponent {
  state: ITreeState;
  nodes = [
    { id: 1, isFolder: true, name: 'folder1', children: [
      { id: 2, name: 'file1', isFolder: false },
      { id: 3, name: 'file2', isFolder: false }
    ] },
    { id: 4, isFolder: false, name: 'flatfile1' },
    { id: 5, isFolder: false, name: 'flatfile2' }
  ];

  collapseAll() {
    this.state = {
      ...this.state,
      expandedNodeIds: {}
    };
  }

  hideFolders() {
    const hiddenNodeIds = {};

    this.nodes.forEach((node) => {
      if (node.isFolder) {
        hiddenNodeIds[node.id] = true;
      }
    });

    this.state = {
      ...this.state,
      hiddenNodeIds
    };
  }
}

!important note

You must have an 'id' property on the nodes in order for this to work. Otherwise - the tree will automatically generate internal IDs which change every time you change the nodes array.

Persist state to localstorage

This example is using the 2 way binding to tree state to auto save & restore from localstorage:

<tree-root
	[(state)]="state"
  [nodes]="nodes">
</tree-root>

class MyComponent {
  get state() {
    return localStorage.treeState && JSON.parse(localStorage.treeState);
  }
  set state(state) {
    localStorage.treeState = JSON.stringify(state);
  }
}

Demo:

Using API

Alternatively, you can use getState, setState and subscribe on treeModel API.
subscribe will callback a function every time state changes.

<tree-root
	#tree
  (initialize)="onInit(tree)"
  [nodes]="nodes">
</tree-root>

class MyComponent {
  onInit(tree) {
    if (localStorage.treeState) {
    	tree.treeModel.setState(JSON.parse(localStorage.treeState);
    }
    tree.treeModel.subscribe((state) => {
      localStorage.treeState = JSON.stringify(state);
    });
  }
}