zTree的用法,以及父子节点(关系节点)转化为tree结构

var setting = {
    edit: {
        enable: true,
        showRemoveBtn: false,//显示后,节点可删除
        showRenameBtn: false,//显示后,节点可重命名
        drag:{
            isCopy:true,  //允许复制
            isMove:false, //允许移动
            prev:false,   //允许插在前面
            inner:false,  //允许插在里面
            next:false     //允许插在后面
        }
    },
    data: {
        simpleData: {
            enable: true
        }
    },
    callback: {
        beforeDrag: beforeDrag,
        beforeDrop: beforeDrop
    }
};

var setting2 = {
    edit: {
        enable: true,
        showRemoveBtn: true,
        showRenameBtn: true,
        drag:{
            isCopy:false,
            isMove:true,
            prev:false,
            inner:true,
            next:false
        }
    },
    data: {
        simpleData: {
            enable: true,
            idKey: "id",
            pIdKey: "pId",
            rootPId: 0
        }
    },
    callback: {
        beforeDrag: beforeDrag,
        beforeDrop: beforeDrop
    }
};

var zNodes2 =[
    { id:1, pId:0, name:"fast", open:true, myAttr:"root"},//额外的属性帮助显示不同的图标
                              //如果用自带level,拖动之后图标会乱,项目特性需要绑定到节点上
    { id:2, pId:1, name:"ceph10", open:true, myAttr:"host"},
        { id:5, pId:2, name:"osd.0"},
        { id:6, pId:2, name:"osd.1"},
        { id:7, pId:2, name:"osd.2"},
        { id:8, pId:2, name:"osd.3"},
    { id:3, pId:1, name:"ceph20", open:true, myAttr:"host"},
        { id:9, pId:3, name:"osd.4"},
        { id:10, pId:3, name:"osd.5"},
        { id:11, pId:3, name:"osd.6"},
        { id:12, pId:3, name:"osd.7"},
    { id:4, pId:1, name:"ceph30", open:true, myAttr:"host"},
        { id:13, pId:4, name:"osd.8"},
        { id:14, pId:4, name:"osd.9"},
        { id:15, pId:4, name:"osd.10"},
        { id:16, pId:4, name:"osd.11"},

    { id:21, pId:0, name:"default", open:true, myAttr:"root"},
    { id:22, pId:21, name:"ceph10", open:true,  myAttr:"host"},
        { id:25, pId:22, name:"osd.0"},
        { id:26, pId:22, name:"osd.1"},
        { id:27, pId:22, name:"osd.2"},
        { id:28, pId:22, name:"osd.3"},
    { id:23, pId:21, name:"ceph20", open:true, myAttr:"host"},
        { id:29, pId:23, name:"osd.4"},
        { id:30, pId:23, name:"osd.5"},
        { id:31, pId:23, name:"osd.6"},
        { id:32, pId:23, name:"osd.7"},
    { id:24, pId:21, name:"ceph30", open:true, myAttr:"host"},
        { id:33, pId:24, name:"osd.8"},
        { id:34, pId:24, name:"osd.9"},
        { id:35, pId:24, name:"osd.10"},
        { id:36, pId:24, name:"osd.11"}
];

function beforeDrag(treeId, treeNodes) {
    //更加深入的定制启动点的条件
    for (var i=0,l=treeNodes.length; i<l; i++) {
        if (treeNodes[i].drag === false) {
            return false;
        }
    }
    return true;
}
function beforeDrop(treeId, treeNodes, targetNode, moveType) {
    //更加深入的定制落点的条件
    if (targetNode && targetNode.myAttr==undefined){
        return false
    }

    return targetNode ? targetNode.drop !== false : true;
}

function fixIcon(demotree){
    var treeObj = $.fn.zTree.getZTreeObj(demotree);
    //过滤出某一类的节点,选出myAttr=='host'的节点
    var folderNode = treeObj.getNodesByFilter(function (node) { return node.myAttr=="host"});
    for(j=0 ; j<folderNode.length; j++){//遍历目录节点,设置isParent属性为true;
        folderNode[j].isParent = true;
        folderNode[j].icon="/static/images/8.png";
    }

    var folderNode = treeObj.getNodesByFilter(function (node) { return node.myAttr=="root"});
    for(j=0 ; j<folderNode.length; j++){//遍历目录节点,设置isParent属性为true;
        folderNode[j].isParent = true;
        folderNode[j].iconOpen="/static/images/1_open.png";
        folderNode[j].iconClose="/static/images/1_close.png"
    }
    treeObj.refresh();//调用api自带的refresh函数。
}
function fixopen(demotree) {
    var treeObj = $.fn.zTree.getZTreeObj(demotree);
    var folderNode = treeObj.getNodesByFilter(function (node) { return node.myAttr=="host" || node.myAttr=="root"});
    for(j=0 ; j<folderNode.length; j++){//遍历目录节点,设置isParent属性为true;
        folderNode[j].open = true;
    }
    treeObj.refresh();//调用api自带的refresh函数。

}
//异步加载数据,数据格式如zNodes2定义的地方
zNodes2 = JSON.parse(arg.topo);
$.fn.zTree.init($("#treeDemo2"), setting2, zNodes2);
fixIcon("treeDemo2");
fixopen("treeDemo2");

父子节点(关系节点)的列表,转化成tree的算法:、

from collections import namedtuple
 #原始机构 
Relation = namedtuple("RELATION",["name","id","pId","myAttr"])
#舒型结构,多一个children,其他语言可以用类或者结构体实现也一样
Tree = namedtuple("TREE",["name","id","pId","myAttr","children"]) 

    
#需要保证关系列表是有序的,否则父节点没有插入就插入字节点会失败
#如果实在不保序, 解决办法建立一个节点添加标志的字典,失败的重复添加
def make_tree(nodes):
    res = Tree("super", 0, 0, "super", []) #根节点,不同语言根节点生成不一样
    for node in nodes:
        add_tree(res, node)
    return res

def add_tree(root, node):
    data = Tree(node["name"], node["id"], node["pId"], node["myAttr"], [])
    if node["pId"]== root.id: #只有符合条件的才真正添加
        root.children.append(data)
        return
    for child in root.children: #可迭代对象自动判空
        add_tree(child,node) #所有节点都尝试添加

def traverse_tree(res, root):
    if root:
        res.append(Relation(root.name, root.id, root.pId, root.myAttr)._asdict())
        for child in root.children:
            traverse_tree(res, child)
#逆向操作,树生成关系节点
def tree_to_relation(root):
    res =[]
    traverse_tree(res, root)
    return res

项目中还遇到js的问题,后台传的数据给前台下拉列表;下拉列表(本身也是异步数据,生成的时候会清空再存入选项)会触发监听,相互覆盖的下拉选项;目前解决是后台数据传给下拉框的时候,不调用trigger,并且也传入完整的下拉列表和选中情况;

也许有办法直接根据后台数据,直接修改下拉列表的选中选中情况;

//ztree定制节点例如iconfont,或者不同颜色背景的方法
view:{
    fontCss:getFont,  //或取单独css样式
    nameIsHTML:true,  //允许name是html
    showTitle:false, //不显示原始的html
    showIcon:showIcon,
}
//选择pId>0的节点当作叶子节点
var folderNode = treeObj.getNodesByFilter(function (node) {
    return node.pId;
});
for (j = 0; j < folderNode.length; j++) {//遍历目录节点
    // folderNode[j].icon = "/static/images/8.png";
    if(folderNode[j].name.indexOf('>')>0){
        folderNode[j].font= {'color':'red'};
        folderNode[j].name= "<i class='iconfont icon-shengji'></i>"+folderNode[j].name;
    }else{
        folderNode[j].font= {'color':'#0037ff'};
        folderNode[j].name= "<i class='iconfont icon-bubian'></i>"+folderNode[j].name;
    }
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值