如何在 Angular 7 中创建延迟加载树视图
How to create a lazy load treeview in Angular 7
我正在使用 Angular 创建一个 TreeView
创建 treeview 的场景是我对每个级别都有不同的 API 意味着如果我单击其中一个父级别节点,那么只有子节点应该只为该特定节点生成,依此类推进一步级别和每个子节点列表来自 API
现在的问题是,当我在创建的树视图中创建嵌套列表时,单击任何节点。正在为该节点和其他节点生成子节点。
这是我的代码。
<ul>
<li *ngFor="let item of companyList" [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>
注意:每个列表都来自单独的 API,这些点击事件有助于调用 API。
请帮助我解决上述问题,在此先感谢。
您可以通过列表中父项的索引来跟踪不同的数据集(例如,如果某个项目从列表中删除并且索引发生变化,则首选 id)
public locationData = {};
load locationData(item, index):
this.locationData[index] = getDataForItem(item);
.....
<ul>
<li *ngFor="let item of companyList; let companyIndex = index;" [id]="item.id">
<span (click)="getLocation(item, companyIndex)">{{item.description}}</span>
<ul>
<li *ngFor="let loc of loactionData[companyIndex]; 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>
您正在为每个嵌套 ul
重复相同的嵌套列表。
您必须将嵌套列表与其父项相关联。
由于您的 companyList 项目和您的 locationData 项目有一个 ID,使用这个 ID 将嵌套列表关联到每个公司和每个位置。
要进行关联,请使用一个简单的对象在您的代码中创建一个地图,并使用索引签名键入它。在您的情况下,它看起来像这样:
companyList: Company[] = [];
locationData: { [companyId: string]: Location[] } = {};
departmentData: { [locationId: string]: Department[] } = {};
然后在您的模板中,您需要使用 item.id
和 loc.id
:
索引 locationData
和 departmentData
<ul>
<li *ngFor="let item of companyList" [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>
生成数据时,将其放在对象中正确的 ID 下:
getLocation(item: Company): void {
this.http.get<Location[]>(`${this.api}/locations?companyId=${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 comment of comments[post.id]">
<span>{{ comment.name }}</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/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.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
users: User[] = [];
posts: { [id: number]: Post[] } = {};
comments: { [id: number]: Comment[] } = {};
private api = 'https://jsonplaceholder.typicode.com';
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}/comments?postId=${post.id}`).subscribe(comments => {
this.comments[post.id] = comments;
})
}
}
我正在使用 Angular 创建一个 TreeView 创建 treeview 的场景是我对每个级别都有不同的 API 意味着如果我单击其中一个父级别节点,那么只有子节点应该只为该特定节点生成,依此类推进一步级别和每个子节点列表来自 API
现在的问题是,当我在创建的树视图中创建嵌套列表时,单击任何节点。正在为该节点和其他节点生成子节点。
这是我的代码。
<ul>
<li *ngFor="let item of companyList" [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>
注意:每个列表都来自单独的 API,这些点击事件有助于调用 API。
请帮助我解决上述问题,在此先感谢。
您可以通过列表中父项的索引来跟踪不同的数据集(例如,如果某个项目从列表中删除并且索引发生变化,则首选 id)
public locationData = {};
load locationData(item, index):
this.locationData[index] = getDataForItem(item);
.....
<ul>
<li *ngFor="let item of companyList; let companyIndex = index;" [id]="item.id">
<span (click)="getLocation(item, companyIndex)">{{item.description}}</span>
<ul>
<li *ngFor="let loc of loactionData[companyIndex]; 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>
您正在为每个嵌套 ul
重复相同的嵌套列表。
您必须将嵌套列表与其父项相关联。
由于您的 companyList 项目和您的 locationData 项目有一个 ID,使用这个 ID 将嵌套列表关联到每个公司和每个位置。
要进行关联,请使用一个简单的对象在您的代码中创建一个地图,并使用索引签名键入它。在您的情况下,它看起来像这样:
companyList: Company[] = [];
locationData: { [companyId: string]: Location[] } = {};
departmentData: { [locationId: string]: Department[] } = {};
然后在您的模板中,您需要使用 item.id
和 loc.id
:
locationData
和 departmentData
<ul>
<li *ngFor="let item of companyList" [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>
生成数据时,将其放在对象中正确的 ID 下:
getLocation(item: Company): void {
this.http.get<Location[]>(`${this.api}/locations?companyId=${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 comment of comments[post.id]">
<span>{{ comment.name }}</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/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.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
users: User[] = [];
posts: { [id: number]: Post[] } = {};
comments: { [id: number]: Comment[] } = {};
private api = 'https://jsonplaceholder.typicode.com';
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}/comments?postId=${post.id}`).subscribe(comments => {
this.comments[post.id] = comments;
})
}
}