zTree异步获取,默认展开一级节点

zTree官网

https://treejs.cn/v3/api.php

涉及到zTree的异步获取

这里主要是在setting部分的设置:

setting: {
	...,
	async: {enable: true, url: getUrl },
	callback: {    //回调函数,实现展开功能
		beforeAsync: beforeAsync,
		onAsyncSuccess: onAsyncSuccess,
		onAsyncError: onAsyncError
	}
}

// 获取树对象,这里参数是树组件objId
$.fn.zTree.getZTreeObj('recorders')

// 展开节点
zTree.expandNode(nodes[i], true, false, false);

// 刷新树
zTree.refresh();

参考文章的封装代码

文章链接: https://www.dandelioncloud.cn/article/details/1537353471057838082

点击查看原文章代码
<input type="button" value="为该角色添加功能" οnclick="addFunction()">
      <ul id="areaTree4" class="ztree"></ul>
</div>
 <script type="text/javascript">
 var setting2 = {
	check: {enable: true},
	async: {enable: true, url: getUrl },
	data: {//数据
		key: { name: "functionName"  },
		simpleData: {
			enable: true,
			idKey: "functionId",       //id
			pIdKey: "pid"              //pid
		}
	},
	callback: {    //回调函数,实现展开功能
		beforeAsync: beforeAsync,
		onAsyncSuccess: onAsyncSuccess,
		onAsyncError: onAsyncError
	}
}
var curStatus = "init", curAsyncCount = 0, asyncForAll = false, goAsync = false;
// 默认注入两个参数,第一个是当前树的名字,第二个是选中的节点
function getUrl(treeId, treeNode){
	return "/roleProject/FunctionServlet?dir=getFunctionTree&functionId="+treeNode.functionId+"&roleNo="+key;
}

function filter(treeId, parentNode, childNodes) {
	if (!childNodes) return null;
	for (var i=0, l=childNodes.length; i<l; i++) {
		childNodes[i].name = childNodes[i].name.replace(/\.n/g, '.');
	}
	return childNodes;
}

// 异步获取前
function beforeAsync() {
	curAsyncCount++;
}

// 异步获取成功
function onAsyncSuccess(event, treeId, treeNode, msg) {
	curAsyncCount--;
	if (curStatus == "expand") {
		expandNodes(treeNode.children);
	} else if (curStatus == "async") {
		asyncNodes(treeNode.children);
	}
	if (curAsyncCount <= 0) {
		if (curStatus != "init" && curStatus != "") {
			asyncForAll = true;
		}
		curStatus = "";
	}
}

// 异步获取错误
function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) {
	curAsyncCount--;
	if (curAsyncCount <= 0) {
		curStatus = "";
		if (treeNode!=null) asyncForAll = true;
	}
}

// 自定义展开全部节点的方法
function expandAll() {
	var zTree = $.fn.zTree.getZTreeObj("areaTree4");
	if (asyncForAll) {
		zTree.expandAll(true);
	} else {
		expandNodes(zTree.getNodes());
		if (!goAsync) {
			curStatus = "";
		}
	}
}

// 自定义展开部分节点
function expandNodes(nodes) {
	if (!nodes) return;
	curStatus = "expand";
	var zTree = $.fn.zTree.getZTreeObj("areaTree4");
	for (var i=0, l=nodes.length; i<l; i++) {
		zTree.expandNode(nodes[i], true, false, false);
		if (nodes[i].isParent && nodes[i].zAsync) {
			expandNodes(nodes[i].children);
		} else {
			goAsync = true;
		}
	}
}

// 使用
var zNodes2=[{functionId:0, functionName:"功能", pid:-1, isParent:true, checked:true }];
$(document).ready(function(){
	$.fn.zTree.init($("#areaTree4"), setting2, zNodes2);
	expandAll();  //调用写好的展开全部节点方法
});
</script>

修改后

因为我的需求是展开至第二级,而且组件的使用代码不同,对于上面的代码进行了改造

组件配置代码
var testTree = {
    lazy: true,
    zTree: '',
    pNode: '',
    jqueryObj: null,
    objId: '',
    setting: {
        check: { enable: true },
        isSimpleData: true,
        treeNodeKey: 'id',
        treeNodeParentKey: 'pid',
        showLine: true,
        async: {
            //异步
            enable: true,
            url: getUrl,
        },
        root: {
            isRoot: true,
            nodes: [],
        },
        showLine: true,
        view: {
            dblClickExpand: false,
            showLine: false,
            selectedMulti: false,
        },
        callback: {
			// 展开节点触发
            onExpand: function (event, treeId, treeNode) {
                testTree.pNode = treeNode
                testTree.loadNodeByPNode()
            },
			// 勾选复选框触发
            onCheck: function (event, treeId, treeNode) {
                testTree.pNode = treeNode
                testTree.zTreeOnCheck(treeNode)
                let { checked, id, pid } = treeNode
                console.log(checked, id, pid)
                $.ajax({
                    url: $('[name=context]').val() + '/4g/openapi/railway/device/find', //后台数据请求地址
                    type: 'get',
                    dataType: 'json',
                    data: {
                        id: id,
                        pid: pid,
                    },
                    async: false,
                    success: function (result) {
                        console.log(result)
                    },
                })
            },
            // 回调函数,实现展开功能
            // 异步获取并展开至第二级,
            beforeAsync: beforeAsync,
            onAsyncSuccess: onAsyncSuccess,
            onAsyncError: onAsyncError,
        },
    },
    //加载根节点,pid=null, treeElement=dev
    loadRootNode: function (jqueryObj, objId) {
        testTree.objId = objId
        testTree.jqueryObj = jqueryObj

        var context = $('[name=context]').val()
        var zNodes = []
        var parameter = null
        $.get(context + '/4g/openapi/railway/organizaton/find', parameter, function (data) {
            $.each(data, function (i, item) {
                var html = {
                    id: item.id,
                    pid: item.pid,
                    name: item.name,
                    open: false,
                    noR: false,
                    isParent: true,
                    parent: true,
                }
                zNodes[i] = html
            })
            $.fn.zTree.init(testTree.jqueryObj, testTree.setting, zNodes)
            testTree.zTree = $.fn.zTree.getZTreeObj(testTree.objId)

            // 默认列出二级节点,这里展开一级节点但是没有触发获取二级节点
            let treeObj = $.fn.zTree.getZTreeObj('recorders')
            let nodes = treeObj.getNodesByParam('level', 0)
            for (var i = 0; i < nodes.length; i++) {
                // 异步加载Tree 想要默认展开全部节点,使用普通的方法是不行的。
                // 设置节点展开
                // treeObj.expandNode(nodes[i], true, false, true)
                // expandAll();
                expandNodes(nodes)
            }
        })
    },
	// 加载子节点
    loadNodeByPNode: function () {
        var context = $('[name=context]').val()
        var children = []
        var folder = false
        var parameter = null
        var url =
            context + '/4g/openapi/railway/organizaton/find?id=' + testTree.pNode.id + '&pid=' + testTree.pNode.pid
        //获取pid = mid的数据,也就是子节点的id等于父节点的id,说明此父节点加载了子节点
        if (!testTree.zTree.getNodeByParam('pid', testTree.pNode.id)) {
            $.get(url, parameter, function (data) {
                $.each(data, function (o, item2) {
                    var html2 = {
                        id: item2.id,
                        pid: item2.pid,
                        name: item2.name,
                        open: false,
                        isParent: true,
                    }
                    folder = false //item2.checked;
                    children[o] = html2
                })
                testTree.zTree.addNodes(testTree.pNode, children, folder)
            })
        }
    },
	// 勾选节点复选框触发
    zTreeOnCheck: function (treeNode) {
        // console.log(treeNode)
        if (treeNode.checked == true) {
        } else {
        }
    },
	// 选择节点触发
    selectNodes: function () {
        var selectIds = ''
        var treeObj = $.fn.zTree.getZTreeObj(testTree.objId)
        return treeObj.getCheckedNodes(true)
    },
}
改造后的代码
var curStatus = 'init',
    curAsyncCount = 0,
    asyncForAll = false,
    goAsync = false

function beforeAsync() {
    curAsyncCount++
}
function onAsyncSuccess(event, treeId, treeNode, msg) {
    curAsyncCount--
	// 这里需要配置子节点的isParent属性,不然默认为叶子节点
    treeNode.children = treeNode.children.map((row) => {
        row.isParent = true
        return row
    })
	// 这里我尝试去掉,不展开子节点,但是去掉之后会影响我的子节点展示为可展开节点
    if (curStatus == 'expand') {
        expandNodes(treeNode.children)
    } else if (curStatus == 'async') {
        asyncNodes(treeNode.children)
    }
	// 取消状态,不再往下展开,
    curStatus = ''
	// 因为expandNodes也没再往下获取,上面展开子节点会导致展开图标是展开了但是底下无数据
	// 遍历然后设置子节点不展开
    treeNode.children = treeNode.children.map((row) => {
        row.open = false
        return row
    })
    var zTree = $.fn.zTree.getZTreeObj('recorders')
	// 刷新树重置子节点的展开状态
    zTree.refresh();
}
function onAsyncError(event, treeId, treeNode, XMLHttpRequest, textStatus, errorThrown) {
    curAsyncCount--
    if (curAsyncCount <= 0) {
        curStatus = ''
        if (treeNode != null) asyncForAll = true
    }
}

function expandAll() {
    var zTree = $.fn.zTree.getZTreeObj('recorders')
    if (asyncForAll) {
        zTree.expandAll(true)
    } else {
        expandNodes(zTree.getNodes())
        if (!goAsync) {
            curStatus = ''
        }
    }
}
function expandNodes(nodes) {
    if (!nodes) return
    curStatus = 'expand'
    var zTree = $.fn.zTree.getZTreeObj('recorders')
    for (var i = 0, l = nodes.length; i < l; i++) {
        //打开节点 ,第一个参数表示哪个节点,第二个参数表示展开还是关闭,第三个参数表示 是否打开全部子孙节点
        zTree.expandNode(nodes[i], true, false, false)
        if (nodes[i].isParent && nodes[i].zAsync) {
			// 因为我这里只需要展开一级节点,所以这里不继续打开底下子节点
            // expandNodes(nodes[i].children)
        } else {
            goAsync = true
        }
    }
}
// 这里改成自己获取子节点的接口
function getUrl(treeId, treeNode) {
    //默认注入两个参数,第一个是当前树的名字,第二个是选中的节点
    var context = $('[name=context]').val()
    var url = context + '/4g/openapi/railway/organizaton/find?id=' + treeNode.id + '&pid=' + treeNode.pid
    return url
}
posted @ 2022-08-08 11:02  ~LemonWater  阅读(1301)  评论(0编辑  收藏  举报