最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to create a lazy load treeview in Angular 7 - Stack Overflow

programmeradmin0浏览0评论

I am creating a TreeView using Angular and the scenario of creating treeview is I have different API for each level means if I click on one of the parent level nodes then only child node should generate for that particular node only and so on for further level and every child node list is ing from API

Now the issue is when I'm creating a nested list to the created tree view, on the click of any node. A child node is generating for that node and other nodes also.

Here is my code.

<ul>
    <li *ngFor="let item of panyList" [id]="item.id">
        <span (click)="getLocation(item)">{{item.description}}</span>
      <ul>
          <li *ngFor="let loc of loactionData" [id]="loc.id">
          <span (click)="getDepartment(loc)">{{loc.description}}</span>
          <ul>
            <li *ngFor="let depart of deaprtmentData">
              <span (click)="getEmpStatus(depart)">{{depart.description}}</span>
            </li>
           </ul>
          </li>
    </ul>
  </li>
</ul>

Note: Every list is ing from separate API and these click event helps to call API.

Please help me with the above issue thanks in advance.

I am creating a TreeView using Angular and the scenario of creating treeview is I have different API for each level means if I click on one of the parent level nodes then only child node should generate for that particular node only and so on for further level and every child node list is ing from API

Now the issue is when I'm creating a nested list to the created tree view, on the click of any node. A child node is generating for that node and other nodes also.

Here is my code.

<ul>
    <li *ngFor="let item of panyList" [id]="item.id">
        <span (click)="getLocation(item)">{{item.description}}</span>
      <ul>
          <li *ngFor="let loc of loactionData" [id]="loc.id">
          <span (click)="getDepartment(loc)">{{loc.description}}</span>
          <ul>
            <li *ngFor="let depart of deaprtmentData">
              <span (click)="getEmpStatus(depart)">{{depart.description}}</span>
            </li>
           </ul>
          </li>
    </ul>
  </li>
</ul>

Note: Every list is ing from separate API and these click event helps to call API.

Please help me with the above issue thanks in advance.

Share Improve this question edited Mar 24, 2019 at 14:04 HDJEMAI 9,82048 gold badges76 silver badges98 bronze badges asked Mar 15, 2019 at 11:07 VIVEKVIVEK 2971 gold badge5 silver badges18 bronze badges 1
  • Can you share the stackblitz? – Prashant Pimpale Commented Mar 18, 2019 at 9:27
Add a ment  | 

2 Answers 2

Reset to default 6 +50

You are repeating the same nested lists for each nested ul. You have to associate your nested lists to their parents.

Since your panyList items and your locationData items have an id, use this id to associate the nested lists to each pany and to each location.

To do the association, create a map in your code using a simple object and type it with an index signature. In your case it will look something like this:

panyList: Company[] = [];
locationData: { [panyId: string]: Location[] } = {};
departmentData: { [locationId: string]: Department[] } = {};

Then in your template, you need to index locationData and departmentData using item.id and loc.id:

<ul>
  <li *ngFor="let item of panyList" [id]="item.id">
    <span (click)="getLocation(item)">{{ item.description }}</span>
    <ul>
      <li *ngFor="let loc of locationData[item.id]" [id]="loc.id">
        <span (click)="getDepartment(loc)">{{ loc.description }}</span>
        <ul>
          <li *ngFor="let depart of departmentData[loc.id]">
            <span (click)="getEmpStatus(depart)">{{ depart.description }}</span>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

When you generate your data, place it under the right id in the objects:

getLocation(item: Company): void {
  this.http.get<Location[]>(`${this.api}/locations?panyId=${item.id}`).subscribe(locations => {
    this.locationData[item.id] = locations;
  })
}

getDepartment(location: Location): void {
  this.http.get<Department[]>(`${this.api}/departments?locationId=${location.id}`).subscribe(departments => {
    this.departmentData[location.id] = departments;
  })
}

Here is an example with a User/Post/Comment data model and the jsonplaceholder API.

See this Stackblitz demo for a live example

<ul>
  <li *ngFor="let user of users" [id]="user.id">
    <span (click)="getPosts(user)">{{ user.name }}</span>
    <ul>
      <li *ngFor="let post of posts[user.id]" [id]="post.id">
        <span (click)="getComments(post)">{{ post.title }}</span>
        <ul>
          <li *ngFor="let ment of ments[post.id]">
            <span>{{ ment.name }}</span>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/mon/http';
import { Observable, of } from 'rxjs';

interface User {
  id: number;
  name: string;
  username: string;
  email: string;
}

interface Post {
  userId: number;
  id: number;
  title: string;
  body: string;
}

interface Comment {
  postId: number;
  id: number;
  name: string;
  email: string;
  body: string;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.ponent.html',
  styleUrls: [ './app.ponent.css' ]
})
export class AppComponent implements OnInit {
  users: User[] = [];
  posts: { [id: number]: Post[] } = {};
  ments: { [id: number]: Comment[] } = {};

  private api = 'https://jsonplaceholder.typicode.';

  constructor(private http: HttpClient) { }

  ngOnInit(): void {
    this.http.get<User[]>(`${this.api}/users`).subscribe(users => this.users = users);
  }

  getPosts(user: User): void {
    this.http.get<Post[]>(`${this.api}/posts?userId=${user.id}`).subscribe(posts => {
      this.posts[user.id] = posts;
    })
  }

  getComments(post: Post): void {
    this.http.get<Comment[]>(`${this.api}/ments?postId=${post.id}`).subscribe(ments => {
      this.ments[post.id] = ments;
    })
  }
}

You could keep track of the different datasets via their parent's index in the list (id would be prefered in case an item gets deleted from the list and the indexes change for example)

public locationData = {};

load locationData(item, index):

this.locationData[index] = getDataForItem(item);

....

<ul>
            <li *ngFor="let item of panyList; let panyIndex = index;" [id]="item.id">
              <span (click)="getLocation(item, panyIndex)">{{item.description}}</span>
              <ul>
                <li *ngFor="let loc of loactionData[panyIndex]; let locationIndex = index;" [id]="loc.id">
                  <span (click)="getDepartment(loc, locationIndex)">{{loc.description}}</span>
                  <ul>
                    <li *ngFor="let depart of deaprtmentData[locationIndex]; let departmentIndex = index;">
                      <span (click)="getEmpStatus(depart, departmentIndex)">{{depart.description}}</span>

                    </li>
                  </ul>
                </li>
              </ul>
            </li>
          </ul>
发布评论

评论列表(0)

  1. 暂无评论