Angular项目中迭代生成的树,激活选中的节点,并将节点数据发送到父节点

从后台返回的数据,还有多层子节点,需要一个生成树的组件,如果直接在页面上写循环来拼接感觉会很麻烦,因为数据的层级结构不固定。

参考网上其他人的方法,整理如下:

1. 创建一个用于循环迭代的组件,在父组件的元素上绑定需要递归的数据和递归组件的选择器。

<ul class="list-wrapper" [treeData]="circuitList" [originalData]="circuitList" (sendNode)="getCurrentNode($event)" tpl-tree-node></ul>

2. 在递归的子组件中接收父组件传入的数据,并在其模板中调用递归组件自身:

<li *ngFor="let item of treeData">
    <a [ngClass]="{'active':item.active}" (click)="getCurrentNode(item)">
        <span class="glyphicon mini-icon" *ngIf="item.children" (click)="toggleSubNode(item)"
              [ngClass]="{'glyphicon-triangle-bottom':item.open,'glyphicon-triangle-right':!item.open}"></span>{{item.name}}</a>
    <ul *ngIf="item.children" [ngClass]="{'show':item.open,'hidden':!item.open}" [treeData]="item.children"
        (sendNode)="getCurrentNode($event)" [originalData]="treeData" tpl-tree-node></ul>
</li>

子组件的ts代码

import {Component, EventEmitter, Input, Output} from "@angular/core";

@Component({
    selector: '[tpl-tree-node]',
    templateUrl: './tpl-tree-node.component.html',
    styleUrls: ['./tpl-tree-node.component.css']
})
export class TplTreeNodeComponent {
    @Input() treeData = [];

    @Input() originalData;

    @Output() sendNode: EventEmitter<any> = new EventEmitter<any>();

    constructor() {
    }

    getCurrentNode(item) {
        this._formatList(this.originalData);
        item.active = true;
        this.sendNode.emit(item);
    }

    private _formatList(arr) {
        arr.forEach(node => {
            node.active = false;
            if (node.children) this._formatList(node.children);
        });
    }

    toggleSubNode(item) {
        item.open = !item.open;
    }
}

按照以上,树组件已经可以正常生成。

同时在点击节点时添加一个激活的样式,取消掉其他节点的激活样式,并将节点对应的数据发送到父组件。

这里比较特别的是递归组件的选择器的定义:

selector: '[tpl-tree-node]',

3. 与参考链接里面不同的是,多定义了一个@Input() originalData,并在子组件中也绑定了这个属性。

这里是为了取消其他树节点的激活样式。不绑定这个初始数据的话,节点点击时,传入的treeData会变成绑定的item.children的数据。即只处理当前节点并列及以下子节点的状态。

4. 从子组建中发送事件到父组件时,一开始没有在子组件内部迭代的部分也绑定事件,导致部分子节点不会发送事件。

参考链接:https://blog.csdn.net/oneloser/article/details/92086914

原文地址:https://www.cnblogs.com/viola-sh/p/11271178.html