<view class="tree"> <block a:for="{{datas}}" a:key="index"> <view class="tree-item"> <label class="tree-item-left"> <am-checkbox ctrlChecked="{{item.checked}}" onChange="onCheckChange" data-item="{{item}}" /> <view class="tree-item-left-label">{{item.name}}</view> </label> <view class="tree-item-right" onTap="dropChange" data-item="{{item}}" a:if="{{item.organizationDTOList && item.organizationDTOList.length > 0}}"> <am-icon type="{{item.dropStatus ? 'UpOutline' : 'DownOutline'}}" color="#979797" size="x-small" /> </view> </view> <view class="tree-child" a:if="{{item.organizationDTOList && item.organizationDTOList.length > 0 && item.dropStatus}}"> <tree datas="{{item.organizationDTOList}}" fuData="{{fuData}}" onDropChange="{{dropChange}}" type="{{type}}"/> </view> </block> </view> import { findNodeInTree, } from '/utils/xym'; Component({ data: { isConfirm: false, // 确认是否可点击 }, props: { datas: [], fuData: [], // onCheckChange: () => {}, onDropChange: () => { }, type: "" }, didMount() { this.$page.tree = this; // 通过此操作可以将组件实例挂载到所属页面实例上 }, didUpdate(prevProps, prevData) { console.log('didUpdate', this.props.datas); }, didUnmount() { }, methods: { // 勾选 onCheckChange(e) { console.log(111, this); const { item } = e.target.dataset; const changeData = this.changeItem(item, !item.checked); this.$page.onCheckChange(item, changeData, this.props.type); }, findItemInTree(datas, item) { const length = datas.length; for (let i = 0; i < length; i++) { if (datas[i].id === item.id) { datas[i] = item; break; } if (datas[i].organizationDTOList && datas[i].organizationDTOList.length) { this.findItemInTree(datas[i].organizationDTOList, item); } } return datas; }, changeItem(item, value) { //点击自己,做全选反选 // 通过isChecked判断是否为选中状态:1-选中;0-未选中。这个字段是后端接口返回的 let addData=JSON.parse(JSON.stringify(this.props.fuData)) let objItem= this.refreshAllSonNodes(item, value);// 根据当前点击层级的状态设置自己所有子级的状态 let newarr1=this.findItemInTree(addData,objItem) // 个人理解:组件每次递归调用会生成一个实例,this指向这个实例,这些实例相互独立的,所以每次的this都不一样,具体可以控制台打印看下。 let newData= this.refreshAllParentNodes(objItem,newarr1) // 设置父级状态 console.log('newarr1',addData,newarr1); return newarr1 }, refreshAllSonNodes(item, value) { item.checked = value; if (item.organizationDTOList && item.organizationDTOList.length) { const child = item.organizationDTOList; child.forEach(ele => { this.refreshAllSonNodes(ele, value); }); } return item; }, refreshAllParentNodes(item,allNodes) { // 点击子节点已经更新完数据,再去操作父节点 this.props.fuData // item.checked = value; console.log('refreshAllParentNodes',item); let currentnode = item // return if (currentnode) { // 该状态说明当前点击层级和兄弟层级都没选中,所以父级也是未选中状态 let parentItemArr = item&&this.findParents(allNodes,item.id) // 找到当前父级赋值, let parentItem = parentItemArr[0] // 找到当前父级赋值, console.log('parentItemArr',parentItemArr,parentItem); let brotherNodes =parentItem&& parentItem.organizationDTOList var status = false; var nullCount = 0; var fullCount = 0; if (parentItem) { brotherNodes.map((meunItem, j) => { if (!meunItem.checked) { nullCount++ } else { fullCount++ } }) // if (nullCount === brotherNodes.length) { //nullCount==4 // // 该状态说明当前点击层级和兄弟层级都没选中,所以父级也是未选中状态 // status = false; // } else { // //该状态说明当前点击层级和兄弟层级只要有一个选中,父级也是选中状态(0<nullCount<4 ||nullCount==0 可以做区分半选中和全选中) // status = true; // } if (nullCount === brotherNodes.length) { //nullCount==4 // 该状态说明当前点击层级和兄弟层级都没选中,所以父级也是未选中状态 status = false; } else { //该状态说明当前点击层级和兄弟层级只要有一个选中,父级也是选中状态(0<nullCount<4 ||nullCount==0 可以做区分半选中和全选中) // status = true; if (nullCount==0) { status = true; }else{ status = false; } } this.findNodeInTree(allNodes, parentItem.id, (item, index, arr) => { console.log('findNodeInTree',parentItem,item); item['checked'] = status }) } console.log('end....',allNodes, parentItem); // // 递归计算父级 this.refreshAllParentNodes(parentItem,allNodes); // if (parentItem&&parentItemArr.length>1) { // this.refreshAllParentNodes(parentItem); // } } }, findNodeInTree (data, key, callback) { for (let i = 0; i < data.length; i++) { if (data[i].id == key) { return callback(data[i], i, data) } if (data[i].organizationDTOList) { this.findNodeInTree (data[i].organizationDTOList, key, callback) } } }, findParents(treeData,id){ if(treeData.length==0) return for(let i=0;i<treeData.length;i++){ if(treeData[i].id == id){ return [] }else{ if(treeData[i].organizationDTOList){ let res = this.findParents(treeData[i].organizationDTOList,id) if(res !== undefined){ return res.concat(treeData[i]) } } } } }, // 展开 / 收起 dropChange(e) { console.log('onDropChange孩子', this.$page, this.props, JSON.stringify(this.props.onDropChange)); const { item } = e.target.dataset; item.dropStatus = !item.dropStatus; // this.props.onDropChange(item,this.props.fuData) this.$page.onDropChange(item, this.props.fuData, this.props.type); }, } }); /* .tree {} */ .tree-item { display: flex; justify-content: space-between; align-items: center; margin-bottom: 32rpx; } .tree-item-left { display: flex; align-items: center; } .tree-item-left-label { margin-left: 17rpx; } .tree-child { padding-left: 52rpx; } // <tree datas="{{otherDatas}}" fuData="{{otherDatas}}" type="2"></tree> 父级引用 import { querySchoolOrgList } from '/utils/service/xym' import { findNodeInTree, } from '/utils/xym'; const a = [ { id:1, value:'一年级', checked:false, children:[ { id:2, value:'一年级1班', checked:false, children:[ { id:6, value:'一年级1班01', checked:true, children:[ { id:10,value:'一年级1班001', checked:true } ] } ]}, {id:3,value:'一年级2班',checked:false}, {id:4,value:'一年级3班',checked:false}, ]}, {id:5,value:'二年级',checked:false,children:[ {id:11,value:'二年级1班',checked:false} ]}, {id:7,value:'三年级',checked:false,children:[ {id:8,value:'三年级1班',checked:false} ]} ] Page({ data: { datasOrization: a, datas: [], otherDatas: [], schoolId: '' }, onLoad(option) { this.setData({schoolId:option.schoolId},()=>{ this.getSchoolOrgList(); }) }, addItemStatusTree(datas) { const length = datas.length; for (let i = 0; i < length; i++) { datas[i].dropStatus = false; datas[i].checked = false; if (datas[i].organizationDTOList && datas[i].organizationDTOList.length) { this.addItemStatusTree(datas[i].organizationDTOList); } } // console.log(datas, 'datasdatasdatas'); return datas; }, newTree(datas,type) { const length = datas.length; for (let i = 0; i < length; i++) { // datas[i].dropStatus = false; // datas[i].checked = false; if(datas[i].type==type) if (datas[i].organizationDTOList && datas[i].organizationDTOList.length) { this.addItemStatusTree(datas[i].organizationDTOList); } } // console.log(datas, 'datasdatasdatas'); return datas; }, async getSchoolOrgList() { const params = { "schoolId": this.data.schoolId, "type": '' } const result = await querySchoolOrgList(params); console.log('result',result); const new1 = []; // 班级组织 const new2 = []; // 其它组织 result.forEach(item => { if (`${item.type}` === '0') { new1.push(item) } else { new2.push(item) } }) const newList1 = this.addItemStatusTree(new1); // 班级组织 const newList2 = this.addItemStatusTree(new2); // 其它组织 this.setData({ datas: newList1, otherDatas: newList2 }); }, // 组织:勾选 onCheckChange(item,fuData,type) { // item.check和children下的check都改变 // console.log('2222222222222222'); // const { datas } = this.data; console.log(' 点击checkobox',item,fuData,type); const list =fuData if (type==1) { this.setData({ datas: JSON.parse(JSON.stringify(list)), }); } if (type==2) { this.setData({ otherDatas: JSON.parse(JSON.stringify(list)), }); } }, // 组织:展开 / 收起 onDropChange(item,fuData,type) { // item.dropStatus改变 console.log(' 组织:展开 / 收起父亲页面',item,fuData,type); // const { datas } = this.data; const list = this.findItemInTree(fuData, item); if (type==1) { this.setData({ datas: JSON.parse(JSON.stringify(list)), }); } if (type==2) { this.setData({ otherDatas: JSON.parse(JSON.stringify(list)), }); } }, // 递归datas,改变里面的值 findItemInTree(datas, item) { const length = datas.length; for (let i = 0; i < length; i++) { if (datas[i].id === item.id) { datas[i] = item; break; } if (datas[i].organizationDTOList && datas[i].organizationDTOList.length) { this.findItemInTree(datas[i].organizationDTOList, item); } } return datas; }, findNodeInTree (data, result=[]) { for (let i = 0; i < data.length; i++) { if (data[i].checked) { result.push(data[i]) } if (data[i].organizationDTOList) { this.findNodeInTree (data[i].organizationDTOList, result) } } }, // 一年级:一班、二班 // 二年级:一班、二班 handleSave() { const staffPositionList = []; let allChildrenBox = []; // console.log(this.data.datas, 'datasdatasdatasdatas'); let arr = [] let arr1 = [] this.findNodeInTree([... this.data.datas,...this.data.otherDatas],arr) this.findNodeInTree([... this.data.datas],arr1) console.log('handleSave',arr); console.log(arr, 'staffPositionList'); getApp().globalData.staffPositionList = arr;// 包括选中的班级和其他岗位 getApp().globalData.allClass = [...arr1]; my.navigateBack(); return [... this.data.datas,...this.data.otherDatas].forEach(item => { // type=0,班级组织 type=1其他组织。暂时只取俩级 但是多级别的全选反选已经实现 let flag = false; let itemChildrenBox = []; if (item.checked) { flag = true item.organizationDTOList.forEach(v => { if (v.checked) { itemChildrenBox.push({ id: v.id, name: v.name, }) if (`${ v.type}`==='0') { allChildrenBox.push(v) } } }) } // console.log(itemChildrenBox, 'itemChildrenBoxitemChildrenBox'); if (flag) { staffPositionList.push({ id: item.id, name: item.name, organizationDTOList: itemChildrenBox }) } }) console.log(staffPositionList,allChildrenBox, 'staffPositionList'); getApp().globalData.staffPositionList = staffPositionList;// 包括选中的班级和其他岗位 getApp().globalData.allClass = [...allChildrenBox]; my.navigateBack(); } });
浙公网安备 33010602011771号