先看實(shí)現(xiàn)的功能縮略圖
業(yè)務(wù)需求:
(1) 省行政區(qū)域?qū)蛹?jí)頁增加“全國”字段,支持全選和全不選設(shè)備權(quán)限
(2) 若子層級(jí)的設(shè)備權(quán)限全部選中涯冠,則上級(jí)組織展示選中狀態(tài),如圖1
(3) 若子層級(jí)的設(shè)備權(quán)限有部分選中逼庞,則上級(jí)組織展示為半選中狀態(tài)功偿,如圖3,4
(4) 若子層級(jí)的設(shè)備權(quán)限全部未選中往堡,則上級(jí)組織展示為非選中狀態(tài)械荷,如圖2
( 5 ) 可直觀定位和追溯當(dāng)前組織所擁有的攝像機(jī)權(quán)限信息
( 6 ) 各層級(jí)展示已選數(shù)量/全部數(shù)量(例:已選2/10),用于展示在各地區(qū)已選的設(shè)備權(quán)限情況虑灰,展示格式:已選X/Y吨瞎,其中X表示當(dāng)前行政區(qū)域內(nèi)已選擇的設(shè)備數(shù)量,Y表示當(dāng)前行政區(qū)域內(nèi)全部設(shè)備數(shù)量
實(shí)現(xiàn)思路
每一個(gè)單元格item都有3種狀態(tài)標(biāo)識(shí)穆咐,selecteTag分為0颤诀,1,2对湃。0是未選中崖叫,1是半選中,2是選中狀態(tài)拍柒。點(diǎn)擊復(fù)選框選中和非選中的方法里心傀,同時(shí)向上和向下遞歸處理,向上拿著該item的上級(jí)組織的id遞歸遍歷所有上級(jí)組織拆讯,同時(shí)根據(jù)012的邏輯給上級(jí)組織selecteTag賦值脂男;向下如果該item的存在子級(jí),就把所有子級(jí)遞歸賦值selecteTag為0或者2种呐。同時(shí)只對(duì)設(shè)備進(jìn)行處理宰翅,在選中的數(shù)組newCheckList中進(jìn)行添加或刪除操作。
實(shí)現(xiàn)代碼
核心代碼
/** 選中當(dāng)前的值
* @param {Object} e
* @param {Object} item 當(dāng)前項(xiàng)
* @param {Object} index 索引
*/
checkboxChange(e, item, index) {
uni.showLoading({
title: '正在加載,請(qǐng)稍候'
});
console.log('點(diǎn)擊chechckBox', e.detail.value, item);
let that = this;
var data = that.newCheckList;
let findIdex = -1; //that.newCheckList.indexOf(item)
for (let i in data) {
if (data[i].deviceCode == item.deviceCode) {
findIdex = i;
break;
}
}
console.log('選中的數(shù)組中的第幾個(gè)', findIdex);
if (e.detail.value && e.detail.value > 0) {
// 點(diǎn)擊選中
if (!item.children && !item.deviceCode) {
console.log('選中第一級(jí)', item);
// 遍歷找到item的上級(jí)爽室,賦值選中
this.partRadioEach(this.parent_data, item.id, 1);
//第一級(jí)的選中
this.parentSelected(item.id, 1);
} else {
that.tree[index].selecteTag = 2
if (item.deviceCode && findIdex < 0) {
that.newCheckList.push(that.tree[index]);
}
console.log('選中de', that.newCheckList);
var childrendata = that.tree[index].children;
if (childrendata && childrendata.length > 0) {
that.selectedDown(childrendata);
}
}
} else {
// 點(diǎn)擊不選
if (!item.children && !item.deviceCode) {
console.log('取消選中第一級(jí)', item);
// 遍歷找到item的上級(jí)汁讼,賦值不選中
this.partRadioEach(this.parent_data, item.id, 0);
//第一級(jí)的不選中
this.parentSelected(item.id, 0);
} else {
if (item.deviceCode) {
that.newCheckList.splice(findIdex, 1);
}
that.tree[index].selecteTag = 0
var cancledata = that.tree[index].children;
console.log('取消刪除', cancledata);
if (Array.isArray(cancledata) && cancledata.length > 0) {
that.deleteDown(cancledata);
}
}
}
that.parentforEach(that.parent_data, item.pid);
console.log('最后的選中數(shù)組', this.newCheckList, item.pid);
that.checckNewList();
this.topSelString = this.getTopChooseItem();
that.$forceUpdate(); //強(qiáng)制更新數(shù)據(jù)
uni.hideLoading();
},
第一個(gè)item的選中和非選中事件,因?yàn)榈谝粋€(gè)item在上級(jí)也存在
//遍歷找到選中的item,賦值選中或不選中
partRadioEach(arr, itemid, tag) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id == itemid) {
if (tag == 1) {
arr[i].selecteTag = 2;
} else {
arr[i].selecteTag = 0;
}
}
if (Array.isArray(arr[i].children) && arr[i].children.length > 0) {
this.partRadioEach(arr[i].children, itemid, tag);
}
}
},
只對(duì)設(shè)備進(jìn)行處理嘿架,在選中的數(shù)組newCheckList中進(jìn)行添加或刪除操作
//第一個(gè)item的選中和非選中卜录,只對(duì)設(shè)備進(jìn)行處理,在選中的數(shù)組newCheckList中進(jìn)行添加或刪除操作
parentSelected(pid, tag) {
for (let i in this.tree) {
var treechildata = this.tree[i].children;
if (tag == 1) {
let item = this.tree[i];
item.selecteTag = 2;
//判斷是否是設(shè)備
if (item.deviceCode) {
let findIdex = -1;
for (let i in this.newCheckList) {
if (this.newCheckList[i].deviceCode == item.deviceCode) {
findIdex = i;
break;
}
}
if (findIdex < 0) {
this.newCheckList.push(item);
}
}
if (treechildata && treechildata.length > 0) {
this.selectedDown(treechildata);
}
} else {
this.tree[i].selecteTag = 0;
var List = this.newCheckList;
console.log('刪除第一眶明、選中的數(shù)組', this.newCheckList);
let Idex = -1;
for (let j in List) {
if (List[j].deviceCode) {
if (List[j].deviceCode == this.tree[i].deviceCode) {
Idex = j;
this.newCheckList.splice(Idex, 1);
break;
}
}
}
if (treechildata && treechildata.length > 0) {
this.deleteDown(treechildata);
}
}
};
},
向下遞歸選中
//向下遞歸選中最底層設(shè)備
selectedDown(arr) {
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
item.selecteTag = 2;
//如果是設(shè)備的話艰毒,才加入選中的數(shù)組
if (item.deviceCode) {
let findIdex = -1;
for (let i in this.newCheckList) {
if (this.newCheckList[i].deviceCode == item.deviceCode) {
findIdex = i;
break;
}
}
if (findIdex < 0) {
this.newCheckList.push(item);
}
}
if (Array.isArray(arr[i].children) && arr[i].children.length > 0) {
this.selectedDown(arr[i].children);
}
}
},
向下遞歸刪除
//向下遞歸刪除
deleteDown(data) {
var List = this.newCheckList;
console.log('刪除、選中的數(shù)組', this.newCheckList);
for (let i in data) {
if (Array.isArray(data) && data.length > 0) {
let Idex = -1;
for (let j in List) {
if (List[j].deviceCode) {
if (List[j].deviceCode == data[i].deviceCode) {
Idex = j;
this.newCheckList.splice(Idex, 1);
break;
}
}
}
data[i].selecteTag = 0;
if (Array.isArray(data[i].children) && data[i].children.length > 0) {
this.deleteDown(data[i].children);
}
}
};
console.log('向下刪除循環(huán)后的選中數(shù)組', this.newCheckList);
},
根據(jù)上級(jí)組織id搜囱,遞歸遍歷所有上級(jí)丑瞧,根據(jù)子層級(jí)的設(shè)備權(quán)限是否選中,給上級(jí)組織狀態(tài)賦值
//遍歷所有上級(jí)賦值
parentforEach(arr, itempid) {
for (let i = 0; i < arr.length; i++) {
//是上級(jí)的處理
if (arr[i].id == itempid) {
var sum = 0;
var subdata = arr[i].children //.splice(0, 1);
for (let j in subdata) {
sum += subdata[j].selecteTag ? subdata[j].selecteTag : 0;
}
sum = sum - (subdata[0].selecteTag ? subdata[0].selecteTag : 0);
console.log('遍歷父級(jí)', sum, arr[i].children.length);
if (sum >= (arr[i].children.length - 1) * 2) {
// 子級(jí)全部選中時(shí)上級(jí)組織也選中
arr[i].selecteTag = 2;
if (arr[i].children[0]) {
arr[i].children[0].selecteTag = 2;
console.log('選中上級(jí)', arr[i]);
}
} else if (sum == 0) {
// 子級(jí)全部不選中時(shí)上級(jí)組織也不選中
console.log('不選中', arr[i]);
arr[i].selecteTag = 0
if (Array.isArray(arr[i].children) && arr[i].children.length > 0) {
arr[i].children[0].selecteTag = 0;
}
} else {
// 子級(jí)有選中且非全部選中的時(shí)候蜀肘,上級(jí)組織時(shí)半選中
console.log('半選中', arr[i]);
arr[i].selecteTag = 1;
if (Array.isArray(arr[i].children) && arr[i].children.length > 0) {
arr[i].children[0].selecteTag = 1;
}
}
this.$forceUpdate(); //強(qiáng)制更新數(shù)據(jù)
if (arr[i].pid && Number(arr[i].pid) != 0) {
this.parentforEach(this.parent_data, arr[i].pid);
}
return;
}
if (Array.isArray(arr[i].children) && arr[i].children.length > 0) {
this.parentforEach(arr[i].children, itempid);
}
}
},