从动态数据后端在Mat Tree中显示子项



我需要您关于Mat Tree与动态数据和延迟加载的帮助。我在Angular找到了这个例子https://stackblitz.com/run?file=src%2Fapp%2Ftree-dynamic-example.ts但我有一个不同的数据结构。我可以看到家长,但无法加载孩子。它的父对象本身就是这样一个对象。

{
"description":"Test Purpose",
"childDevices":8,
"childLocations":8,
"name":"Test",
"id":"1234556788www2"
}

然后为了加载更多的信息或孩子,我需要创建一个Get请求,它会像这样返回给我。

{
"id": "1234556788www2",
"name": "Test",
"description": "Test Purpose",
"parent": null,
"children": [
"1st Child ID",
"2nd Child ID"
],
"groupsV2": [
"group ID"
],
"usersV2": [
"userID"
],
"tenantId": "Tenant ID",
"devices": [
"device1 ID",
"device2 ID",
"device3 ID",
"device4 ID"
]
}

现在,为了得到它的子项,我需要再次通过API get迭代,这样我就可以得到每个子项的信息,然后在父项下的树上显示。我花了很多时间,没有找到如何带孩子们到树上。这是每个子级的JSON。

{
"id": "1st Child ID",
"name": "TestLocation",
"description": "333",
"parent": "1234556788www2",
"children": [],
"groupsV2": [

],
"usersV2": [

],
"tenantId": "",
"devices": []
}

这是我的HTML。

<mat-tree [dataSource]="dataSource" [treeControl]="treeControl" data-cy="locationsMatTree">
<mat-tree-node>
<mat-nested-tree-node
*matTreeNodeDef="let node; when: hasChild"
[class.hidden]="!node.visible"
[class.fe-action]="node.overallFEChildCount > 0"
[class.be-action]="node.overallFEChildCount < node.overallChildCount">
<div class="title mat-tree-node on-hover">
<button mat-icon-button matTreeNodeToggle *ngIf="node.childLocations > 0; else noLocations">
<mat-icon class="mat-icon-rtl-mirror" (click)="loadChildren(node)">
{{ treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right' }}
</mat-icon>
</button>
<ng-template #noLocations>
<button mat-icon-button>
<mat-icon class="no-sub-icon">
<span class="leaf-icon"> • </span>
</mat-icon>
</button>
</ng-template>
<div
class="location-name hide-in-percy"
(click)="loadDevices(node)"
[routerLink]="['/location/details', node.id]"
[id]="'created-' + node.name">
{{ node.name }}
</div>
<icon-button
color="primary"
*ngIf="!isDisabled"
iconName="add"
type="mat-icon-button"
class="action-button action-button-add"
(click)="onNewClicked(node)">
</icon-button>
<icon-button
color="primary"
type="mat-icon-button"
iconName="edit"
class="action-button action-button-edit"
(click)="onEditClicked(node)">
</icon-button>
<icon-button
color="warn"
type="mat-icon-button"
iconName="delete"
class="action-button action-button-delete"
[disabled]="node.action?.generated"
[matTooltipDisabled]="!node.action?.generated"
matTooltip="{{ 'RIGHT_ACTIONS_DISABLED_LEAF' | translate }}"
(click)="deleteLocation(node)">
</icon-button>
</div>
<ul [class.tree-invisible]="!treeControl.isExpanded(node)">
<ng-container matTreeNodeOutlet></ng-container>
</ul>
<mat-progress-bar *ngIf="node.isLoading" mode="indeterminate" class="example-tree-progress-bar"></mat-progress-bar>
</mat-nested-tree-node>
</mat-tree-node>
</mat-tree>

TS代码。

private readonly subscription: Subscription = new Subscription();
dataSource = new MatTreeNestedDataSource<Location>();
hasChild = (_: number, node: Location) => !!node.childLocations && node.childLocations > 0;

this.locationService
.getLocationsForUser(this.pageIndex, this.pageSize)
.pipe(take(1))
.subscribe((response) => {
this.dataSource.data = response.body.content; // here I load all parents
this.flatLocations = this.getFlatLocations();
this.length = response.body.totalElements;
if (response.body.content && response.body.content.length > 0) {
this.location = response.body.content[0];
this.loadDevices(this.location);
}
this.subscribeToRouteParams();
});
}

loadChildren = (location: Location): any => {
this.locationService.getLocation(location.id).subscribe((res) => {
for (let i = 0; i < res.body.children.length; i++) {
this.locationService.getLocation(res.body.children[i]).subscribe((t) => {
return of(t.body); //Here I can see each child data
});
}
});
return false;
};

您当前的问题是在loadChildren函数中嵌套订阅。您可能希望使用switchMapforkJoin并行调用this.locationService.getLocation(),并输出数组中每个调用的响应:

loadChildren = (location: Location): any => {
this.locationService.getLocation(location.id).pipe(
switchMap(res => forkJoin(
res.body.children.map(child => this.locationService.getLocation(child))
)
)
).subscribe( resultArray => {
location.childLocations = resultArray;
});
}

最新更新