需求
有兩個數據類,一個是樹形最底層的成員數據userList。一個樹形中的部門數據depList,利用這兩類數據形成樹形。
數據
// 成員數據
const userList = [{
id: 1,
name: '張三',
avatar: 'http://...',
depId: 1
},{
id: 2,
name: '李四',
avatar: 'http://...',
depId: 2
}]
// 部門數據
const depList = [{
id: 1,
name: '部門1',
parentId: 0
},{
id: 2,
name: '部門1',
parentId: 1
}]
分析
形成樹形網上有很多方法都可以,我這裏根據需求進行改造,利用Object對象引用的特殊性(引用的Object改變後會改變原始Object)來實現這樹形結構。再把樹形數據填充到樹形生成插件zTree中去。
考慮幾點內容:
- 部門下是否無成員(出現空部門時當如何處理);
- 部門下是否無部門(出現部門下存在空部門時當如何處理);
- 部門下是否同時擁有成員及部門
源碼
1、首先把成員數據按部門歸個類
/**
* 對成員按depId分組
* @param {Array} d 成員數據
* return Object 以部門爲鍵值的成員對象
*/
groupUser(d){
var users = {}
for(var i = 0; i < d.length; i++){
if(users[d[i].depId]){
users[d[i].depId].push(d[i])
}else{
users[d[i].depId] = [d[i]]
}
}
return users;
}
2、再計算樹形
/**
* 部門架構樹形圖
* @param {Array} d 部門信息
* return Object
*/
groupDep(d){
// 拿取成員信息map
var usersMap = this.groupUser(userList)
// 將部門數據存儲爲以id爲key的map
var depMap = {}
d.forEach(function (item){
depMap[item.id] = item
})
var depTree = []
d.forEach(function(item){
// 以當前遍歷項的parentId,去depMap對象中找到索引的id(如找到則說明當前項存在父級)
var parent = depMap[item.parentid]
// 以當前遍歷項的id,去usersMap對象中找到索引的id
var users = usersMap[item.id]
// 如果找到當前部門下的成員數據,那麼把相關人員追加到此項中
if(users){
if(item.children){
item.children = item.children.concat(users)
}else{
item.children = users
}
}else{
// 如果部門下無員工(此處處理部門下無成員時需要給當前部門添加一個屬性depNone=true)
var depChild;
// 查找有無子部門
for(var key in depMap){
if(depMap[key].parentid == item.id) depChild = true; // 如果不存
}
// 如果沒有,就添加一個屬性depNone=true
// 此屬性可用於zTree中,用來判斷該層是否存在成員,方時可利用它來給isParent設爲true,以文件夾的方法展示。
if(!depChild) item.depNone = true;
}
// 如果找到父級部門,那麼說明此項不在頂級當中,需要把此項添加到對應的父級中
if (parent) (parent.children || (parent.children = [])).push(item)
//如果沒有在depMap中找到對應的索引ID,那麼直接把當前的item添加到depTree結果集中,作爲頂級
else depTree.push(item)
})
return depTree
}
最後再把zTree中設置isParent屬性的方法貼出來
/**
* 設置zTree中的isParent屬性
* @param {String} id 渲染zTree的domID
* return 無
*/
fixIcon(id){
var treeObj = $.fn.zTree.getZTreeObj(id);
//過濾出depNone屬性爲true的節點
var folderNode = treeObj.getNodesByFilter(node => {return node.depNone});
//遍歷目錄節點,設置isParent屬性爲true;
folderNode = folderNode.map(item => {
item.isParent = true;
})
//調用api自帶的refresh函數。
treeObj.refresh();
}
大家有更好的方法實現這需求,請留言,謝謝
注:愛護原創,轉載請說明出處