效果图:
重点ngTemplateOutlet的使用
<div class="mat-padding tb-absolute-fill">
<div class="main-block">
<table class="treeTable">
<tr class="theadTr" id="theadTr">
<td style="width: 60%;">部门名称</td>
<td>操作</td>
</tr>
<tbody>
<ng-container *ngTemplateOutlet="treeNode;context:{$implicit:treeList}"></ng-container>
<ng-template #treeNode let-itemNode>
<ng-container *ngFor="let item of itemNode">
<tr>
<td style="width: 60%;" [ngStyle]="{'padding-left':item.level * 20 + 'px'}">
<button mat-icon-button (click)="item.open=!item.open" >
<mat-icon class="material-icons" *ngIf="item.children&&item.children.length>0">{{
item.open? 'expand_less'
: 'expand_more' }}</mat-icon>
</button>
<span>{{item.orgName}}</span>
</td>
<td>
<button mat-icon-button matTooltip="编辑" matTooltipPosition="above" (click)="editTreeNode(item)">
<mat-icon class="material-icons">edit</mat-icon>
</button>
<button mat-icon-button matTooltip="添加下级组织" matTooltipPosition="above" (click)="addTreeNode(item)">
<mat-icon class="material-icons">add_circle_outline</mat-icon>
</button>
<button mat-icon-button matTooltip="删除" matTooltipPosition="above" (click)="deleteTreeNode(item)">
<mat-icon class="material-icons">delete</mat-icon>
</button>
</td>
</tr>
<ng-container *ngIf="item.children&&item.children.length>0 && item.open">
<ng-container *ngTemplateOutlet="treeNode;context:{$implicit:item.children}"></ng-container>
</ng-container>
</ng-container>
</ng-template>
</tbody>
</table>
</div>
</div>
ts (需引入,不然报错)
ts 代码
treeList = [
{ orgName: '部门1', level: 1, parentName: '', children: [{ orgName: '部门1-1', level: 2, parentName: '部门1', children: [], }] },
{ orgName: '部门2', level: 1, parentName: '', children: [], },
{ orgName: '部门3', level: 1, parentName: '', children: [{ orgName: '部门3-1', level: 2, parentName: '部门1', children: [{ orgName: '部门3-1-1', level: 3, parentName: '部门1', children: []}] }] },
]
// 数据增加open值
addTreeOpenValue(listData) {
for (let item of listData) {
if (item.children && item.children.length > 0) {
this.addTreeOpenValue(item.children);
} else {
item.open = false;
}
}
}
scss:
:host ::ng-deep {
.main-block {
width: 100%;
height: 100%;
// padding: 15px;
background-color: #fff;
position: relative;
}
.treeTable {
border-collapse: collapse;
width: 100%;
tr {
line-height: 50px;
border-bottom: 1px solid #eee;
height: 50px;
&:hover:not(.theadTr) {
background-color: #f4f4f4;
}
}
td {
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
font-size: 13px;
}
.theadTr {
td {
padding-left: 50px;
}
}
}
button.mat-icon-button mat-icon {
color: rgba(0, 0, 0, 0.54);
}
}