我正在尝试构建一个分层展开/折叠列表来表示父级子关系。在初始加载时,将列出父节点。如果他们有孩子,则会显示一个克拉图标,否则就会显示一个子弹图标。单击克拉图标后,将发出API调用来检索数据,并显示子信息。再次单击同一克拉图标时,将不会进行API调用,但直接子列表将被隐藏。如果子节点是父节点,则应该递归地发生这种情况。
期望的初始加载行为:
单击克拉图标以展开:需要的行为:
JSON数据
{
"page": {
"results": [{
"id": "1001",
"title": "American",
"children": {
"page": {
"results": [{
"id": "1003",
"title": "Chevy",
"children": {
"page": {
"results": [],
"start": 0,
"limit": 25,
"size": 0
}
}
}],
"start": 0,
"limit": 25,
"size": 1
}
}
}, {
"id": "1002",
"title": "German",
"children": {
"page": {
"results": [],
"start": 0,
"limit": 25,
"size": 0
}
}
}],
"start": 0,
"limit": 2,
"size": 2
}
}
组件代码
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import { WikiService } from '../wiki.service';
import { WikiTree } from '../../interfaces/WikiTree';
import { AppConfigService } from '../../services/app-config.service';
@Component({
selector: 'app-wiki-tree-nav',
templateUrl: './wiki-tree-nav.component.html',
styleUrls: ['./wiki-tree-nav.component.css']
})
export class WikiTreeNavComponent implements OnInit {
public wikiPageId: any = '1000';
wikiTree$: Observable<WikiTree>;
public resultsPage: any;
constructor(private wikiService: WikiService, private route: ActivatedRoute,
private appConfigService: AppConfigService) {
this.route.params.subscribe(res => this.wikiPageId = res.id);
}
ngOnInit() {
this.getWikiTree(0, 200, this.wikiPageId);
}
getWikiTree(start: number = 0, limit: number = 200, pageId: string = '') {
this.wikiTree$ = this.wikiService.GetWikiTree(start, limit, pageId);
this.wikiTree$.subscribe((data) => {
this.resultsPage = data;
},
(err) => {
}
);
}
getCSSClass(pageId: string) {
let cssClass = '';
if (this.wikiPageId === pageId) {
cssClass = 'boldTitle';
}
return cssClass;
}
}
HTML代码
<ul *ngIf="wikiTree$ | async as wikiTree">
<li *ngFor="let result of wikiTree.page.results; index as i" style="margin-bottom:10px;">
<div>
<span *ngIf="result.children.page.size==0" style="margin-left:4px;margin-right:4px;">
<clr-icon shape="circle" class="is-solid" size="6"></clr-icon>
</span>
<span *ngIf="result.children.page.size>0">
<a (click)="getWikiTree(0,200,result.id)">
<clr-icon shape="caret right" size="14"></clr-icon>
</a>
</span>
<span style="margin-left:5px;font-size:14px;" [ngClass]="getCSSClass(result?.id)">
<a href="/pages/{{result.id}}">{{result.title}}</a>
</span>
</div>
</li>
</ul>
我的当前HTML代码替换了整个树,而不是附加到父节点。如何实现角HTML代码来递归地执行展开和折叠?
发布于 2020-05-20 03:12:12
我去创建一个结构指令,所以我的app.component.html变成了
<div recursive [children]="data" [search]="dataService.getData"></div>
在这里我定义了
constructor(public dataService:DataService){}
ngOnInit()
{
this.dataService.getData(0).subscribe(res=>this.data=res)
}
我需要将"search“函数传递给递归组件,该组件返回一个可观察到的对象数组,对象具有属性'id‘、'label’和'hasChildren‘,以指示是否有子对象,例如,json响应类似于
[{id:1,label:'label1',hasChildren:true},{id:2,label:'label2'}]
在递归组件中,我喜欢定义为@Input()
级别、子级和父级。正如您想要的那样,在单击获取“子”的函数时,我添加搜索,并在“打开”函数中更改属性"isOpen“并调用searchFunction。请注意,在管理组件的对象中,最初没有属性“子”或“isOpen”,我添加了以下“动态”
@Component({
selector: "[recursive]",
templateUrl: "./tree-view.component.html",
styleUrls: ["./tree-view.component.css"]
})
export class TreeViewComponent {
@Input() level: number;
@Input() children: any;
@Input() parent: any;
@Input() search: (any) => Observable<any>;
self = this;
open(item) {
item.isOpen = !item.isOpen;
if (!item.children) {
item.loading="...."
this.search(item.id).subscribe(res=>{
item.loading=null
item.children=res;
})
}
}
}
在这种情况下,我们的树-view.html如下
<ul class="tree" *ngIf="level==undefined">
<ng-container *ngTemplateOutlet="tree;context:{children:children,search:search}">
</ng-container>
</ul>
<ng-container *ngIf="level!=undefined">
<ng-container *ngTemplateOutlet="tree;context:{children:children,search:search}">
</ng-container>
</ng-container>
<ng-template #tree let-children="children" let-search="search">
<li *ngFor="let item of children">
<div (click)="item.hasChildren && open(item)">
<span [ngClass]="!item.hasChildren?'doc':item.isOpen?'open':'close'" ></span>
{{item.label}}{{item.loading}}
</div>
<ul recursive *ngIf="item.children && item.isOpen"
[children]="item.children"
[parent]="self"
[level]="level!=undefined?level+1:0"
[search]="search"
>
</ul>
</li>
</ng-template>
看stackblitz,我希望这对你有帮助
注意:我使用三个css类,.doc、.open和.close来指示树的状态,以及使用of和delay的“傻瓜”服务来模拟调用。
https://stackoverflow.com/questions/61905207
复制