膳绫擎两句代码就完成了递归过程,但实际上情况还要复杂些,因为要处理人口和容错。
- // 留意参数支撑传入单根或多根,
- // 如不雅像 travelWidely 那样只支撑多根(单根是特例)也是可以的
- function travelDeeply(roots: INode | INode[]) {
- function printNode(node: INode) {
- console.log(`${node.name} ${node.nodes && node.nodes.length || ""}`);
- if (node.nodes && node.nodes.length) {
- // 依次对子节点递归调用 printNode
- node.nodes.forEach(child => printNode(child));
- }
- }
- // 这里 printNode 和 node => printNode(node) 等价
- (Array.isArray(roots) ? roots : [roots]).forEach(printNode);
- }
- // 开端遍历
- travelDeeply(data);
关于递归,我正好在慕课网上讲生成数据解决筹划的时刻讲到了,有兴趣可以看看。
遍历还没讲完
看看源码(转译成 JS 之后的):http://jsfiddle.net/y7bw4yj2/
膳绫擎两种遍历都讲到了,然则还没讲完——因为两种遍历都是以打印为例,而我们的目标是要生成 DOM 树。生成 DOM 树与纯打印信息的不合之处在于,我们不仅要应用节点信息,还要大年夜节点信息生成 DOM 返回出来。
此次先讲深度遍历,因为递归更轻易实现。递归本身具有层次信息,每进入一个递归调用点,就会深刻一层,每分开一个递归停止点,就会削减一层。所以这个算法本身可以或许保存构造信息,响应代码也会更轻易实现。并且在本文一开端,就已经实现出来了。
- function printNode(node: INode) {
- // 处理该节点
- console.log(node.name);
- // 递归调用点:轮回对子节点调用 printNode
- node.nodes!.forEach(child => printNode(child));
- // 递归停止点:轮回完成,return
- }
须要留意的一点是那段代码用了两个函数来完成递归过程:
- makeNode 处理单个节点,它调用 makeNodeList 处理子节点列表
- makeNodeList 遍历节点列表,分别对其调用 makeNode 来进行处理
makeNode 和 makeNodeList 的互相调用形成了递归,上述两条都是递归调用点,而递归停止点同样也有两条:
- makeNode 处理的节点没有子节点时,不会调用 makeNodeList
- makeNodeList 中的轮回停止时,不会再调用 makeNode
广度遍历生成节点
广度遍历的过程是把所有节点扁平化到一个队列中了,这个过程是弗成逆 的,换句话说,我们在处理过程中损掉落了树形构造信息。然后我们要生成的 DOM 树,是须要构造信息的——是以,须要将构造信息附加在每个节点上。这里我们把生成的 DOM 和数据节点绑定起来,由 DOM 保存构造信息。为此,须要修改一下节点类型
- interface INode {
- name: string;
- nodes?: INode[];
- dom: JQuery; // 附加生成的 DOM
- }
- function makeTreeWidely(roots: INode[]): JQuery {
推荐阅读
导致HTTP verb应用欠妥的重要原因在于浏览器对HTTP标准的支撑存在缺点,这是一种汗青遗留问题。在XML HTTP Request(XHR)风行起来之前,我们几乎得依附特定框架和代码库来应用HTTP verb(除了GET和POST之>>>详细阅读
本文标题:使用递归遍历并转换树形数据(以TypeScript为例)
地址:http://www.17bianji.com/lsqh/38416.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示