zTree分批异步加载体式格局下完成节点搜刮功用

媒介

近来公司做一个项目用到zTree,zTree功用壮大就不必多说了,置信用过的人都晓得。
公司项目由于要展现的节点异常多,所以请求要完成搜刮节点的功用,zTree确切很壮大,它供应了getNodesByParamByFuzzy要领可依据关键字举行隐约查询获得想要的节点,极为轻易。然则题目来了,由于要读取节点的数据量很大,节点的数目有几万个以至更多,考虑到机能和时候上的题目,因而不能一次性把悉数节点数据读取出来,这里我采纳的是zTree自带的分批异步加载形式。然则如许就又造成了别的一个题目,再运用getNodesByParamByFuzzy这个要领时便只能找到已加载出来的节点,而没法找到还没有举行加载的节点,从而运用户体验不好。

分批异步加载

加载一切父节点

为了处理这个题目,刚最先的主意是每次都去数据库查询数据,每次只显示搜刮到的第一条效果,然后再举行下一条查询,查到末了一条时又返回第一条,现实如许的思绪是行的通的,然则如许完成起来异常贫苦,而在项目中一般都不止一棵树,难不成每棵树都要如许,为了这小小的功用却要写云云多的代码着实恶心,空话不多说,下面是我本身想的以为比较好的要领。看下面代码:

// 节点加载完的回调函数,加载体式格局照旧是分批加载,然则不是等用户睁开节点才去加
// 载,而是让它自动完成加载,这里不好的处所是照旧要加载悉数数据,所以必需守候
// 它加载完才运用搜刮功用
function onAsyncSuccess(event, treeId, treeNode, msg) {
    var zTreeObj = $.fn.zTree.getZTreeObj();
    // 这个要领是将规范 JSON 嵌套花样的数据转换为简朴 Array 花样
    var nodes = zTreeObj.transformToArray(zTreeObj.getNodes()); 
    for (var i = 0; i < nodes.length; i++) {
        // 推断节点是不是已加载过,假如已加载过则不须要再加载
        if (!nodes[i].zAsync) {
            zTreeObj.reAsyncChildNodes(nodes[i], '', true);
        }
    }
}

守候悉数树节点加载完

所以还必需定义多一个推断树节点是不是已悉数加载完的要领。这个要领我是参考《通晓JavaScript》上面关于守候页面加载完的要领来写的。

function treeAsyncReady(treeId, f) {
    // 假如树已加载完,立时实行函数
    if (treeAsyncReady.done) {
        return f();
    }
    
    var zTreeObj = $.fn.zTree.getZTreeObj();
    
    treeAsyncReady.timer = setInterval(function() {
        if (treeAsyncReady.done) {
            return false;
        }
        
        // 猎取没有异步加载过的节点
        var nodes = zTreeObj.getNodesByFilter(funciton(node) {
            return !node.zAsync;
        });
        // 假如节点数为零则申明已加载完
        if (nodes.length == 0) {
            clearInterval(treeAsyncReady.timer);
            treeAsyncReady.timer == null;
            
            // 实行函数
            f();
            
            treeAsyncReady.done = true;
        }
    }, 13);
}

完成搜刮功用

定义了这个要领,然后就能够在这个要领完成完成你要搜刮的功用了。

treeAsyncReady('treeId', function() {
    // 在这里写搜刮节点的代码
    ...
});

搜刮节点

搜刮节点的功用请求依据关键字隐约婚配节点,而且要睁开节点地点的父节点直到根节点。

function swarchNodes(treeId, keyword) {
    var zTreeObj = $.fn.zTree.getZTreeObj();
    
    // 去掉上一次查询到的节点色彩,假如是第一次搜刮则不必
    if (searchNodes.nodes) {
        var prevNodes = searchNodes.nodes;
        for (var i = 0; i < prevNodes.length; i++) {
            prevNodes[i].highlight = false;
            zTreeObj.updateNode(prevNodes[i]);
        }
        // 收起悉数节点
        zTreeObj.expandAll(false);
    }
    
    // 从新查找节点
    var nodes = zTreeObj.getNodesByParamFuzzy('name', $.trim(keyword));
    for (var i = 0; i < nodes.length; i++) {
        nodes[i].highlight = true;
        zTreeObj.updateNode(nodes[i]);
        
        // 推断是不是是根节点,假如是根节点则不必睁开
        if (nodes[i].level != 0) {
            // 本身定义的一个查找悉数父节点的要领
            var parentNodes = getParentNodes(treeId, nodes[i]);
            // **这里重要睁开节点时必需先从根节点最先睁开,不然会出题目**
            for (var j = parentNodes.length - 1; j >= 0; j--) {
                // 睁开没有睁开的父节点
                if (!parentNodes[j].open) {
                    zTreeObj.expandNode(parentNodes[j], true, false, false);
                }
            }
        }
    }
    
    // 缓查找到的节点
    searchNodes.nodes = nodes;
}

查找悉数父节点

这个要领是查找节点的悉数父节点,直到根父节点。

function getParentNodes(treeId, node, cache) {
    // 缓存变量
    cache = cache || [];
    var zTreeObj = $.fn.zTree.getZTreeObj();
    var parentNode = node.getParentNode();
    // 有父节点则缓存,直到根节点
    if (parentNode != null) {
        cache.push(parentNode);
    } else {
        return cache;
    }
    // 递归挪用查找父节点
    return getParentNodes(treeId, parentNode, cache);
}
    原文作者:naou
    原文地址: https://segmentfault.com/a/1190000004756744
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞