子组件  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.departmentNamethis.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

angular2+ 中封装调用递归tree相关推荐

  1. Angular2 中setTimeOut 回调函数未定义问题

    需求: 在angular2中,调用延时函数,在保存表单成功后,系统下方显示成功信息,在指定时间内若不手动关闭,则提示信息自动关闭. 思路: 保存成功后,调用setTimeout方法,回调函数为关闭提示 ...

  2. php 循环 post,如何在php中使用jQuery递归调用POST循环请求

    如何在php中使用jQuery递归调用POST循环请求 发布时间:2021-01-28 17:37:18 来源:亿速云 阅读:79 作者:Leah 这期内容当中小编将会给大家带来有关如何在php中使用 ...

  3. C# 在自定义的控制台输出重定向类中整合调用方信息

    C# 在自定义的控制台输出重定向类中整合调用方信息 目录 C# 在自定义的控制台输出重定向类中整合调用方信息 一.前言 二.输出重定向基础版 三.输出重定向进阶版(传递调用方信息) 四.后记及资源 独 ...

  4. 中序非递归遍历二叉树

    二叉树的递归算法虽然简单,但是会导致时间复杂度比较高,下面给大家带来用栈实现的二叉树非递归算法 首先定义好二叉树,和元素类型为二叉树的栈 typedef struct BiTNode{TElemTyp ...

  5. openresty开发系列27--openresty中封装redis操作

    openresty开发系列27--openresty中封装redis操作 在关于web+lua+openresty开发中,项目中会大量操作redis, 重复创建连接-->数据操作-->关闭 ...

  6. java sql封装,在Java系统中封装SQL语言的处理方法及系统的制作方法

    在Java系统中封装SQL语言的处理方法及系统的制作方法[ 技术领域: ][0001]本发明涉及计算机数据处理 技术领域: ,特别是涉及一种在Java系统中封装SQL语言的处理方法及系统.[ 背景技术 ...

  7. 如何用堆栈和循环结构代替递归调用--递归转换为非递归的10条军规

    10 Rules (steps) for replacing the recursive function with stack and while-loop 转自http://www.codepro ...

  8. React学习:ref调用、组件封装调用-学习笔记

    文章目录 React学习:ref调用.组件封装调用-学习笔记 ref调用-string形式 ref调用-回调形式(官方推荐) ref调用-父调子 组件封装调用demo(全选) demo1(单组件) d ...

  9. C代码中如何调用C++ C++中如何调用C

    注意这里的C调用C++或者C++调用C意思是.c文件中调用.cpp文件中代码,或者相反. 集成开发环境如VC++6.0或者vs都是以文件后缀来区别当前要编译的是C代码还是C++代码,然后采用响应的编译 ...

  10. 在C++中反射调用.NET(二)

    反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET程序集的简单方法,今天我们看看如何在C+ ...

最新文章

  1. 使用vlc播放m3u8网络视频教程
  2. 百度云使用第三方工具下载文件
  3. DELETE ADJACENT DUPLICATES FROM语句的深入研究及应用
  4. Gitflow branch与Docker image tag命名冲突怎么办?
  5. 分布与并行计算—用任务管理器画CPU正弦曲线(Java)
  6. jdk678910新特性地址
  7. 计算机配置扫盲,扫盲了。。怎么识别电脑配置好坏?
  8. HandlerThread使用
  9. JavaScript案例精解(一)
  10. Windows内核编程学习1:构建HelloWorld
  11. 目标检测---搬砖一个ALPR自动车牌识别的环境
  12. 计算机ppt闪耀效果在哪里,ppt怎样制作文字闪烁效果
  13. Java实现杨辉三角形
  14. 2022-2028年中国农业观光园行业发展战略规划及投资方向研究报告
  15. A到Z的unicode的编码的大小
  16. 关于win10输入法导致电脑直接卡机无法动弹问题
  17. java 第六次实验_操作系统第六次实验报告——使用信号量解决哲学家进餐问题...
  18. 北京君正案例:超能面板PRO采用4英寸IPS超清多彩屏,值不值得买?
  19. C Primer Plus 第五章 编程练习
  20. AD使用笔记1 原理图与PCB布局同步实现

热门文章

  1. js 去空格 和 获得字节数
  2. String.resize()
  3. 垃圾回收机制,是不是这样理解?
  4. Matlab使用心得
  5. SRM 574 DIV1 L2
  6. 《Linux操作系统原理》教学大纲
  7. python时间操作代码
  8. pip 安装 pytorch环境
  9. 【Linux】修改权限命令chmod用法示例
  10. XLM-RoBERTa: 一种多语言预训练模型