angular2+ 中封装调用递归tree
子组件 given-person.html
<!--权限设置-选择员工--> <li [class.noborder]="!dir.shierarchy" *ngFor="let dir of directories" [ngStyle]="{'margin-left': 5+(dir.shierarchy*.5)+'px'}"> <span *ngIf="dir.employee.length && dir[files.filename]"> <i (click)="toggle(dir)" [ngClass]="{ 'file-open': files.icon==='file' && dir.toggle, 'file-close': files.icon==='file' && !dir.toggle }"></i> <input (click)="onAllChecked(dir)" type="checkbox" [(ngModel)]="dir.isChecked"> <em class="filename">{{dir[files.filename]}}</em> </span> <ng-container *ngIf="dir.toggle"> <ng-container *ngIf="dir.employee.length"> <label class="emname" [ngStyle]="{'margin-left': 5+(dir.shierarchy*.5)+'px'}" *ngFor="let em of dir.employee"> <!-- 当部门选中之后,下面的员工都被选中,并禁用掉不让取消勾选 --> <input (click)="callback(em)" type="checkbox" [(ngModel)]="em.isChecked" [disabled]="dir.isChecked"> {{em.emName}}</label> </ng-container> <ng-container *ngIf="dir[files.child]"> <app-given-person [directories]="dir[files.child]" [files]='files' (callbackEvent)="files.callback($event,files.that)"></app-given-person> </ng-container> </ng-container> </li>
子组件 given-person.ts
import {Component, OnInit, Input, Output, EventEmitter, OnChanges} from '@angular/core'; @Component({ selector: 'app-given-person', templateUrl: './given-person.component.html', styleUrls: ['./given-person.component.scss'] }) export class GivenPersonComponent implements OnChanges, OnInit { @Input() directories; @Input() files; @Output() callbackEvent = new EventEmitter(); constructor() { } ngOnInit() { } ngOnChanges() { this.setOrganizsTree(this.directories, 0); console.log(this.directories) console.log(this.files) } // 设置层级 setOrganizsTree(data, shierarchy) { data.forEach(item => { if (!item.isChecked) { item.isChecked = false; } if (!item.shierarchy) { item.shierarchy = shierarchy; } if (!item.toggle) { item.toggle = true; } if (item.departs.length !== 0) { console.log(item.shierarchy); const shierarchy1 = item.shierarchy + 1; this.setOrganizsTree(item.departs, shierarchy1); // 递归 } }); } toggle(dir) { dir.toggle = !dir.toggle; } callback(dir) { // console.log(dir) this.callbackEvent.emit(dir); } // 全选 onAllChecked(dir) { dir.touch = 'touch'; this.callbackEvent.emit(dir); this.checkedAll(dir, !dir.isChecked); } // 全选 checkedAll(dir, bools) { // 点击部门把部门下的所有人选中 if (dir.departs && dir.departs.length !== 0) { dir.departs.forEach(item => { item.isChecked = bools; }); dir.departs.forEach(item => { this.checkedAll(item, bools); item.touch = 'no'; }); } if (dir.employee && dir.employee.length !== 0) { dir.employee.forEach(item => { item.isChecked = bools; }); dir.employee.forEach(item => { this.checkedAll(item, bools); item.touch = 'no'; }); } } }
页面中调用 demo.component.ts
<button (click)="showAddSuperAdmin=true"></button> <!-- 选择发送对象,部门或个人,选择部门时意味着选的是部门下所有人 --> <div class="mask" *ngIf="showAddSuperAdmin"> <div class="alert-content"> <div class="title">选择发送对象<span class="close-btn" (click)="showAddSuperAdmin=false">×</span></div> <div class="container clearFix"> <div class="pull-left"> <div class="tit">选择:</div> <div class="structure"> <form [formGroup]="departsForm" class="search" *ngIf="departsForm"> <input type="text" placeholder="搜索" formControlName="departsNameSearch"> <span class="sear-close" *ngIf="departsForm.get('departsNameSearch').value" (click)="searchTreeClose()">×</span> <img src="../assets/icon/ser.png"> </form> <i style="opacity: 0;height: 1px;overflow: hidden;width:1px;display: inline-block">{{filteredStates | async}}</i> <!-- <orangize-tree [treelist]="menu"></orangize-tree> --> <div class="organiz"> <label class="all" *ngIf="departsFormResult.show"><input type="checkbox" [(ngModel)]="allCheckOrganizsEmployee" (change)="allCheckOrganizsEmployeeEvent()"> 全选 </label> <app-given-person *ngIf="departsFormResult.show" [directories]="organizsTreeOriginal" (callbackEvent)="callbackEvent($event,this)" [files]="filesTree"></app-given-person> <div *ngIf="organizsFilterStaff.length===0">{{departsFormResult.msg}}</div> <ng-container *ngIf="!departsFormResult.show"> <label class="emname" *ngFor="let em of organizsFilterStaff"><input [disabled]="allCheckOrganizsEmployee" (click)="callbackEvent(em,this)" type="checkbox" [(ngModel)]="em.isChecked">{{em.emName}}------{{em.parent}}</label> </ng-container> </div> </div> </div> </div> <div class="btn-wrap"><button class="btn bgblue submit" (click)="onSave()">确定</button></div> </div> </div>
ts
showAddSuperAdmin = false; departsForm: FormGroup; // 部门搜索 departsFormResult = {show: false, msg: '查询中...'}; filteredStates: Observable<string>; organizsTreeOriginal = []; // 左侧树结构原始数据 organizsFilterStaff = []; // 模糊查询显示员工 selectedStaffs = []; filesTree = { 'titleshow': false, 'child': 'departs', 'filename': 'departmentName', 'icon': 'file', 'callback': null, // 在初始函数里面讲callback初始化 this.filesTree.callback = this.callbackEvent; 'that': this }; ngOnInit() { this.filesTree.callback = this.callbackEvent; } selectedDeparts = []; // 部门或人 onSave(){ // 保存发送对象 this.showAddSuperAdmin = false; this.selectedDeparts = []; this._addGiven(this.organizsTreeOriginal); console.log(this.selectedDeparts) this.params.sendTarget = this.selectedDeparts; const arr = []; this.params.sendTarget.forEach(i=>{ arr.push(i.sendName) }) this.addsendName = arr.join(',') }
// 在给后台传参的时候,如果是选择部门就只传部门,相当于会发给部门下所有人,如果是选择的是部门下面的某个或某几个人,就传这几个人和和对应的id,selectedDeparts是要传给后台的参数 _addGiven(data) { data.forEach(item => { if (item.isChecked) { const option = {sendName:item.departmentName, sendEmId:''} this.selectedDeparts.push(option); } if (item.departs.length !== 0 && !item.isChecked) { this._addGiven(item.departs); } if (item.employee.length !== 0&& !item.isChecked) { this._addEmployee(item.employee); } }); } _addEmployee(data){ data.forEach(item=>{ if(item.isChecked){ const option = {sendName:item.emName, sendEmId:item.emId} this.selectedDeparts.push(option) } }) } private allCheckOrganizsEmployee = false; allCheckOrganizsEmployeeEvent() { this._allCheckOrganizsEmployee(this.organizsTreeOriginal, this.allCheckOrganizsEmployee) } _allCheckOrganizsEmployee(data, b) { data.forEach(item => { item.isChecked = b; if (item.employee !== 0) { // 如果有员工 item.employee.forEach(em => { em.isChecked = b; }); } if (item.departs.length !== 0) { // 如果还有部门 this._allCheckOrganizsEmployee(item.departs, b) } }) } // 点击叉叉清空value; searchTreeClose (){ this.departsForm.patchValue({departsNameSearch: ''}); } // 订阅搜索部门 departsNameSearchInit() { this.departsForm = this.fb.group({ departsNameSearch: [''] }) this.filteredStates = this.departsForm.get('departsNameSearch').valueChanges.pipe( startWith(''), debounceTime(300), map(state => { // // console.log(state) if (state === '') { this.departsFormResult.show = true; } else { this.departsFormResult.show = false; } this.organizsFilterStaff = []; this.setPageOrganizsTree(state, this.organizsTreeOriginal) if (this.organizsFilterStaff.length === 0) { this.departsFormResult.msg = `没有查询到 "${state}"`; } return state; }) ); } // 选择发送对象 selectedStaffsEvent(data, type, user?) { data.forEach(item => { if (item.employee !== 0) { // 如果有员工 item.employee.forEach(em => { if (em.isChecked) { this.selectedStaffs.push(em); } }); } if (item.departs.length !== 0) { // 如果还有部门 if (type === 'select' || type === 'reset') { // 选择 或者重置 this.selectedStaffsEvent(item.departs, type); // 递归 } if (type === 'delete') { // 移除 this.selectedStaffsEvent(item.departs, type, user); // 递归 } } }); } // 筛选层级 setPageOrganizsTree(key, data) { for (let i = 0; i < data.length; i++) { const item = data[i]; // 如果有员工 if (item.employee.length !== 0) { for (let j = 0; j < item.employee.length; j++) { const staff = item.employee[j]; if (staff.emName.indexOf(key) !== -1) {// 匹配到 staff.parent = item.departmentName this.organizsFilterStaff.push(staff); // break; } } } // 如果有部门 if (item.departs.length !== 0) { this.setPageOrganizsTree(key, item.departs); } } } // tree callback; callbackEvent(v, that) { console.log(v) that.selectedStaffs = []; setTimeout(() => { that.selectedStaffsEvent(that.organizsTreeOriginal, 'select'); }, 0); }