从数据 API 动态创建递归树视图的最佳方法 [英] Best approach to create recursive treeview dynamically from data API
问题描述
我正在学习 Angular 2,试图从(可能非常大的)第三方 API 构建可扩展的树视图.API 的底层结构如下:
I'm learning Angular 2, trying to build an expandable tree-view from a (potentially very large) third-party API. The API has an underlying structure like this:
- Home (id: 1053)
- - Rugby League (id: 1054)
- - - Super League (id: 1103)
- - - - Castleford Tigers (id: 1111)
- - - - Catalans Dragons (id: 1110)
- - - - Huddersfield Giants (id: 1116)
- - - - Hull FC (id: 1108)
- - - Championship (id: 1104)
- - - - Batley Bulldogs (id: 1120)
- - - - Bradford Bulls (id: 1118)
- - - - Dewsbury Rams (id: 1124)
- - - - Featherstone Rovers (id: 1121)
- - Football (id: 1056)
- - - Premier League (id: 1057)
- - - - AFC Bournemouth (id: 1059)
- - - - etc
- - - - etc
API 的设置使得我传递一个 id 并返回一个简单的 JSON 数组,该数组包含该节点的子节点(仅).因此,例如我调用: http://www.example.com/api/contentNodes/?parentId=1053
并返回:
The API is set up such that I pass an id and it returns a simple JSON array of the children (only) of that node. So, for example I call: http://www.example.com/api/contentNodes/?parentId=1053
and it returns:
(HasChildren
表示节点是否有子节点.)
[
{"Id":1054,"Name":"Rugby League","HasChildren":true},
{"Id":1056,"Name":"Football","HasChildren":true}
]
请注意,因为数据集最终会很大,所以我想在打开树枝时逐渐从 API 中拉入"更多数据,而不是将整个数据集转储到那里并在我的应用.
(HasChildren
represents whether or not the node has child nodes.)
我已经设置了一个 Angular 2 应用程序,可以在这里看到:http://plnkr.co/edit/QQ1OKCbd4pDptpSVbWch?p=preview
Note, because the data-set will eventually be large I want to 'pull in' more data from the API progressively as the tree branches are opened, rather than dumping the entire data-set in there and rendering that out in my app.
关键组件是`app/content-list.component.ts'文件:
I've set up an Angular 2 app which can be seen here: http://plnkr.co/edit/QQ1OKCbd4pDptpSVbWch?p=preview
The key component is the `app/content-list.component.ts' file:
您会在此处看到我正在调用我的服务,该服务通过传递 1053 的 parentId 返回 JSON.
import {Component, OnInit} from 'angular2/core';
import {ContentNode} from './content-node';
import {ContentService} from './content.service';
@Component({
selector: 'content-list',
template: `
<ol class="tree">
<li *ngFor="#contentNode of contentNodes" class="tree__branch" [ngClass]="{'tree__branch--has-children': contentNode.HasChildren}">
<a *ngIf="contentNode.HasChildren" (click)="toggleBranch(contentNode.Id)" class="toggle">+</a> {{ contentNode.Name }}
</li>
</ol>
<div class="error" *ngIf="errorMessage">{{errorMessage}}</div>
`
})
export class ContentListComponent implements OnInit {
constructor (private _contentService: ContentService) {}
errorMessage: string;
private _startNodeId: number = 1053;
contentNodes: ContentNode[];
ngOnInit() {
this.getContentNodes();
}
getContentNodes() {
this._contentService.getContentNodes(this._startNodeId)
.subscribe(
contentNodes => this.contentNodes = contentNodes,
error => this.errorMessage = <any>error
);
}
toggleBranch(branchId:number){
console.log('branchId: ' + branchId);
}
}
我现在在点击 +
按钮时能够将树视图的子节点逐步加载到嵌套的 HTML 列表中(
You'll see here that I'm calling my service which returns the JSON as above, by being passed a parentId of 1053.
- ).
这里最好的方法是什么,以非常简洁的方式实现这一目标?
What would be the best approach here, to achieve this in a really neat way?
我的下一步将是确保应用不会进行过多的 API 调用,但我最关心的只是让正在运行的树视图连接起来并正常工作.
My next step will be to ensure that the app doesn't make excessive API calls, but my immediate concern is just to get a running treeview hooked up and working.
我看过这个递归树视图示例但似乎 (a) 有点问题(因为当子节点为空时,HTML 中会呈现空的 <ol></ol>
元素等);(b) 它似乎是以一种非常硬编码"的方式设置的,我没有足够的经验来自信地重构它.
I've seen this example of a recursive treeview but it seems (a) a little buggy (in that there are empty <ol></ol>
elements rendered in the HTML when child nodes are empty etc); and (b) it seems to be set up in a very 'hard-coded' kind of a way and I'm not experienced enough to confidently refactor it.
非常感谢.
请注意,不幸的是,出于安全原因,我无法向公共请求开放 API,这使得在 Plunkr 上进行测试有点困难,我意识到.目前,我的示例仅使用静态的单级 JSON 数据集.
推荐答案
在 Angular2 中,您可以递归地渲染指令.这使得渲染树非常容易.我已经稍微修改了您的 Plunker 只是为了表明这一点.这不是理想的实现,但它按预期工作:)
in Angular2 you can render directives recursively. This makes rendering the tree very easy. I've modified your Plunker a little bit just to show the point. It's not the ideal implementation but it works as expected :).
示例:
@Component({
selector: 'tree-view',
template: `
<div *ngFor="#dir of dirs">
<tree-view [dirs]="dir.dirs"></tree-view>
<div>
`,
directives: [TreeView]
})
export class TreeView {
@Input()
private dirs: Array<Directory>;
}
希望你会喜欢.
干杯!
这篇关于从数据 API 动态创建递归树视图的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!