Home     Source

SLV Tree (Angular 5)


The tree is populated with help of AJAX request to a server JSONPlaceholder.

There are 3 kinds of items (leafs):

1. User 2. Post 3. Comment

Start with names of users.

  ngOnInit() {
    this.tree = new Tree(this.onClick.bind(this));
    this.reqService.fetchUsers()
      .map(users => users.map(user => new Leaf('name', new User(user), true, 'fa-user'))
      )
      .subscribe(
        (leaves) => {
          this.tree.insertLeaves(leaves);
        },
        () => alert('error')
      );
  }

Description of the code above:

  1. A new Tree object was built. The parameter is a click callback.
  2. Users array fetched from server.
  3. Leaves array created accordingly to users array. Leaf parameters:
    • field name of a User class which used as a label
    • User object to be bound to a leaf
    • a flag if a leaf is parent (branch)
    • symbol of awesome font
  4. The leaves inserted into the tree.

Callback function on leaf click:

onClick(data: User | Post | Comment, isVisited: boolean, leaf: Leaf) {
    // reset selected objects
    this.user = null;
    this.post = null;
    this.comment = null;

    // 1. User
    if (data instanceof User) {

      this.user = {...data};
      if (!isVisited) {
        this.reqService.fetchPosts(data)
          .map(
            posts => {
              return posts.map(post => new Leaf('title', new Post(post), true, 'fa-edit'));
            }
          )
          .subscribe(
            (leaves) => {
              this.tree.insertLeaves(leaves, leaf);
            },
            () => alert('error')
          );
      }
    }

    // 2. Post
    else if (data instanceof Post) {
      this.post = {...data};

      if (!isVisited) {
        this.reqService.fetchComments(data)
          .map(
            comments => {
              return comments.map(comment => new Leaf('name', new Comment(comment), false, 'fa-comment'));
            }
          )
          .subscribe(
            (leaves) => {
              this.tree.insertLeaves(leaves, leaf);
            },
            () => alert('error')
          );
      }
    }
    // 3. comment
    else {
      this.comment = {...data};
    }
  }

The callback gets 3 parameters:

  1. data - object bound to the clicked leaf
  2. isVisited gives a hint if the leaf has already downloaded children leaves
  3. leaf object

If a leaf was not open (visited) previously then need to create its children leaves and insert them into clicked branch (leaf).

A reference to the current object is updated.


Data bound to the selected leaf is changing with help of the following function:

saveDataInLeaf(data: User | Post | Comment) {
    this.tree.setSelectedLeafData(data);
  }

While creating of leaves, a field as a label was pointed out. So changing of its value will be reflected in UI output.

Note: if no need to change a label of leaves then possible to pass some static text instead of a field name. For example, a field value.