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;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); }
原文地址:https://www.cnblogs.com/leiting/p/9321679.html