【问题标题】:Best approach to create recursive treeview dynamically from data API从数据 API 动态创建递归树视图的最佳方法
【发布时间】:2016-04-09 20:37:32
【问题描述】:

我正在学习 Angular 2,试图从(可能非常大的)第三方 API 构建可扩展的树视图。 API 的底层结构如下:

- 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 并返回:

[
  {"Id":1054,"Name":"Rugby League","HasChildren":true},
  {"Id":1056,"Name":"Football","HasChildren":true}
]

HasChildren表示该节点是否有子节点。)

注意,因为数据集最终会很大,所以我想在树枝打开时逐步从 API 中“拉入”更多数据,而不是将整个数据集转储到那里并在我的应用程序。

我已经设置了一个 Angular 2 应用程序,可以在这里看到:http://plnkr.co/edit/QQ1OKCbd4pDptpSVbWch?p=preview

关键组件是 `app/content-list.component.ts' 文件:

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);
    }
}

您会在这里看到,我正在调用我的服务,该服务返回 JSON,方法是传递 1053 的 parentId。

现在,当单击+ 按钮时,能够将树视图的子节点逐步加载到嵌套的 HTML 列表 (&lt;ol&gt;) 中,我现在遇到了困难。

这里最好的方法是什么,以一种非常简洁的方式实现这一目标?

我的下一步将是确保应用不会进行过多的 API 调用,但我最关心的只是让正在运行的树视图连接并正常工作。

我见过this example of a recursive treeview,但它似乎(a)有点错误(因为当子节点为空时,HTML 中呈现了空的&lt;ol&gt;&lt;/ol&gt; 元素等); (b) 它似乎是以一种非常“硬编码”的方式设置的,我没有足够的经验来自信地重构它。

非常感谢。

注意,出于安全原因,很遗憾,我无法向公共请求开放 API,这使得在 Plunkr 上进行测试有点困难,我意识到。目前,我的示例仅使用静态的单级 JSON 数据集。

【问题讨论】:

    标签: treeview angular angular2-services


    【解决方案1】:

    在 Angular2 中,您可以递归地渲染指令。这使得渲染树变得非常容易。 我已经修改了你的Plunker 一点点只是为了说明这一点。这不是理想的实现,但可以按预期工作:)。

    例子:

    @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>;
    }
    

    希望你会喜欢。

    干杯!

    【讨论】:

    • 不错!谢谢。我很想知道理想的实现是什么,因为我的应用程序将非常依赖这个逻辑。如果您有任何时间解释将不胜感激,但无论如何感谢您的工作解决方案! :)
    • 使用 changedetection 锻炼会是一个非常有趣的案例:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多