Angular 2:孩子的递归模板
Posted
技术标签:
【中文标题】Angular 2:孩子的递归模板【英文标题】:Angular 2: Recursive template for child 【发布时间】:2017-06-15 19:00:52 【问题描述】:我正在使用的 API 为我提供了以下结构作为响应:
"data": [
"id": 5,
"name": "First name",
"parent": 0
,
"id": 1,
"name": "Second name",
"parent": 5
,
"id": 6,
"name": "Third name",
"parent": 1
,
"id": 15,
"name": "Fourth name",
"parent": 0
,
"id": 25,
"name": "Fifth name",
"parent": 5
]
我想围绕这个使用ngFor
构建一个树形结构,它支持无限数量的子级别。
这是我迄今为止尝试过的:
<div *ngFor="let d1 of _dataList">
<ul *ngIf="d1.parent == 0">
<li>
d1.name
<ul *ngFor="let d2 of _dataList">
<li *ngIf="d2.parent == d1.id">d2.name</li>
</ul>
</li>
</ul>
</div>
这行得通,但它很难看,我必须手动重复这个 X 级别的数据,从而留下硬编码的限制。
如何优化此代码以支持无限级别 - 并且看起来更好?
【问题讨论】:
这可能有助于***.com/questions/37746516/… 我宁愿说它是重复的 Use component in itself recursively to create a tree的可能重复 您需要格式化您的数据并使用递归结构,如上面链接的问题。您可能应该对其进行格式化,以便每个具有子节点的节点都将它们放在一个数组中,然后您可以更轻松地递归传递数据。 谢谢 Seiyria,我会研究让 API 以不同格式返回列表的可能性。 【参考方案1】:https://stackblitz.com/edit/angular-yij5e5?file=src%2Fapp%2Ftree-view%2Ftree-view.component.ts 注意:下面的代码不是递归的,它是 2d 的,不能用于树渲染。 您应该使用 ng 模板或为其定义一个组件。
<div *ngFor="let d1 of _dataList">
<ul *ngIf="d1.parent == 0">
<li>
d1.name
<ul *ngFor="let d2 of _dataList">
<li *ngIf="d2.parent == d1.id">d2.name</li>
</ul>
</li>
</ul>
</div>
来自http://odyniec.net/articles/turning-lists-into-trees/的css
角度来自https://gist.github.com/arniebradfo/5cf89c362cc216df6fc1d9ca4d536b72
js(如何将平面数组转换为树)来自我:D
[解决方案 1]=>
JS
let xTree = [
"id": 5,
"name": "First name",
"parent": 0
,
...
];
let tree = [
id: 0,
name: 'root',
parent: null,
childs: []
];
let todoList = [];
Converter();
function FindParent(list, el)
if (list.length > 0)
let res = list.find(x => x.id === el.parent);
if (res)
return res;
else
let _res = undefined;
list.forEach(xchild =>
_res = FindParent(xchild.childs, el);
if (res)
return _res;
);
return _res
else
return undefined;
function Converter()
todoList = xTree;
for (let x = 0; x < 90; x++)
todoList.forEach(r =>
let parent = FindParent(tree, r);
if (parent)
if (!parent.childs)
parent.childs = [];
parent.childs.push(r);
todoList = todoList.filter(el => el !== r);
);
html
<ul class="tree">
<ng-template #recursiveList let-list="list">
<li *ngFor="let item of list">
item.name
<ul *ngIf="item.childSet.length > 0">
<ng-container *ngTemplateOutlet="recursiveList; context: list: item.data"></ng-container>
</ul>
</li>
</ng-template>
<ng-container *ngTemplateOutlet="recursiveList; context: list: data"></ng-container>
</ul>
css
ul.tree, ul.tree ul
list-style-type: none;
ul.tree, ul.tree ul
list-style-type: none;
background: url(/assets/vline.png) repeat-y;
margin: 0;
padding: 0;
ul.tree ul
margin-left: 10px;
ul.tree li
margin: 0;
padding: 0 12px;
line-height: 20px;
background: url(/assets/node.png) no-repeat;
color: #369;
font-weight: bold;
ul.tree li:last-child
background: #fff url(/assets/lastnode.png) no-repeat;
【讨论】:
【参考方案2】:你可以有一个递归组件,比如名为TreeComponent
的组件
TreeComponent
的模板会是这样的
<div *ngFor="let item of dataList">
<ul *ngIf="item.parent==parentId">
<li>item.name
<tree [parentId]="item.id" [dataList]="removeCurrentLevelItems(dataList,parentId)"></tree>
</li>
</ul>
</div>
查看link here 以获得现场演示
【讨论】:
嗨,卢卡斯,我找不到从现场演示链接进行编辑的方法。你能帮忙吗? @FengZhang 它不需要权限等进行编辑,您可以尝试分叉到您的一个或检查您的浏览器控制台以查看任何错误以上是关于Angular 2:孩子的递归模板的主要内容,如果未能解决你的问题,请参考以下文章