layui tree子节点的加载处理

众所周知,layui.tree的树形控件,在渲染树节点时,需要后台准备好整个组织树的数据;如果组织树的数据量特别大,页面渲染就特别慢。

步骤1:源码修改

1:打开源码,在树的主渲染方法 r.render前,添加上用于加载child节点的方法r.children,代码如下:

r.children = function (e, i, d) {

var a = l.that[e];

return a.children(i, d)

}

2:找到b.prototype.tree方法,在此方法前,添加两个用于懒加载子节点的方法:b.prototype.children = function (n1, n2) {

var e = this;

e.setchildrendata(e.config.data, n1, n2);

},

b.prototype.setchildrendata = function (n0, n1, n2) {

var e = this;

var c = i(‘#’ + e.config.id);

layui.each(n0, function (a, r) {

var b = c.find('div[data-id=' + r.id + ']').hasClass(C);

r.spread = b;

if (e.config.accordion === !0) { //手风琴模式

  r.spread = !1;

  var cs = c.find('div[data-id=' + n1 + ']').parents('.layui-tree-set');

  cs.each(function () {

    if (r.id === i(this).attr('data-id')) {

      r.spread = !0;

    }

  });

}

if (r.id === n1) {

  r.spread = !0;

  if(!r.children){

    r.children=[];

  }

  if (n2.length === 0) {

    delete r.children;

  }else{

    //i.extend(!0, r.children, n2);

    r.children = n2;

  }

  e.reload(e.config.id, e.config.data);

}

if (r.children) {

  e.setchildrendata(r.children, n1, n2); //递归子节点

}

});

}

3:修改b.prototype.tree方法的代码,修改后代码如下【备注://TODO 部分标识的是layui原始代码】

b.prototype.tree = function (e, a) {

    var n = this, t = n.config, r = a || t.data;

    layui.each(r, function (a, r) {

        //TODO 此处调整源码

        //var l = r.children && r.children.length > 0,

        var l = r.children,

            o = i('<div class="layui-tree-pack" ' + (r.spread ? 'style="display: block;"' : "") + '"></div>'),

            //TODO 源码调整

            //h = i(['<div data-id="' + r.id + '" class="layui-tree-set' + (r.spread ? " layui-tree-spread" : "") + (r.checked ? " layui-tree-checkedFirst" : "") + '">', '<div class="layui-tree-entry">', '<div class="layui-tree-main">', function () {

            h = i(['<div data-id="' + r.id + '" data-parent-id="' + r.parentId + '" class="layui-tree-set' + (r.spread ? " layui-tree-spread" : "") + (r.checked ? " layui-tree-checkedFirst" : "") + '">', '<div class="layui-tree-entry ' + (l ? "taller" : "") + '" >', '<div class="layui-tree-main">', function () {

                //TODO 源码调整

                //return t.showLine ? l ? '<span class="layui-tree-iconClick layui-tree-icon"><i class="layui-icon ' + (r.spread ? "layui-icon-subtraction" : "layui-icon-addition") + '"></i></span>' : '<span class="layui-tree-iconClick"><i class="layui-icon layui-icon-file"></i></span>' : '<span class="layui-tree-iconClick"><i class="layui-tree-iconArrow ' + (l ? "" : c) + '"></i></span>'

                return t.showLine ? l ? '<span class="layui-tree-iconClick layui-tree-icon"><i class="layui-icon ' + (r.spread ? "layui-icon-subtraction" : "layui-icon-addition") + '"></i></span>' : '<span class="layui-tree-iconClick layui-tree-icon"><i class="layui-icon layui-icon-file"></i></span>' : '<span class="layui-tree-iconClick"><i class="layui-icon ' + ( r.spread ? "layui-tree-active" : "layui-tree-iconArrow") + (l ? "" : c)+' "></i></span>'

            }(), function () {

                return t.showCheckbox ? '<input type="checkbox" name="' + (r.field || "layuiTreeCheck_" + r.id) + '" same="layuiTreeCheck" lay-skin="primary" ' + (r.disabled ? "disabled" : "") + ' value="' + r.id + '">' : ""

            }(), function () {

              //TODO 修改源码显示title

              //return t.isJump && r.href ? '<a href="' + r.href + '" target="_blank" class=" + y + ">' + (r.title || r.label || t.text.defaultNodeName) + "</a>" : '<span class="' + y + (r.disabled ? " " + d : "") + '">' + (r.title || r.label || t.text.defaultNodeName) + "</span>"

              return t.isJump && r.href ? '<a title="' + (r.title || r.label || t.text.defaultNodeName) + '"  href="' + r.href + '" target="_blank" class=" + y + ">' + (r.title || r.label || t.text.defaultNodeName) + "</a>" : '<span title="' + (r.title || r.label || t.text.defaultNodeName) + '" class="' + y + (r.disabled ? " " + d : "") + '" >' + (r.title || r.label || t.text.defaultNodeName) + "</span>"

            }(), "</div>", function () {

                if (!t.edit) return "";

                var e = {

                    add: '<i class="layui-icon layui-icon-add-1"  data-type="add"></i>',

                    update: '<i class="layui-icon layui-icon-edit" data-type="update"></i>',

                    del: '<i class="layui-icon layui-icon-delete" data-type="del"></i>'

                }, i = ['<div class="layui-btn-group layui-tree-btnGroup">'];

                return t.edit === !0 && (t.edit = ["update", "del"]), "object" == typeof t.edit ? (layui.each(t.edit, function (a, n) {

                    i.push(e[n] || "")

                }), i.join("") + "</div>") : void 0

            }(), "</div></div>"].join(""));

        l && (h.append(o), n.tree(o, r.children)), e.append(h), h.prev("." + s)[0] && h.prev().children(".layui-tree-pack").addClass("layui-tree-showLine"), l || h.parent(".layui-tree-pack").addClass("layui-tree-lineExtend"), n.spread(h, r), t.showCheckbox && (r.checked && n.checkids.push(r.id), n.checkClick(h, r)), t.edit && n.operate(h, r)

    })

}

4:修改节点展开方法b.prototype.spread,修改后代码如下【备注://TODO 部分标识的是layui原始代码】

b.prototype.spread = function (e, a) {

    var n = this, t = n.config, r = e.children("." + p), l = r.children("." + f), c = r.find("." + o),

        k = r.find("." + y), m = t.onlyIconControl ? c : l, x = "";

    m.on("click", function (i) {

        var ax = e.children("." + v),//TODO a冲突改成ax

            //TODO 修改源码

            //n = m.children(".layui-icon")[0] ? m.children(".layui-icon") : m.find(".layui-tree-icon").children(".layui-icon");

            n = m.children(".layui-icon")[0] ? m.find(".layui-tree-iconClick").children(".layui-icon") : m.find(".layui-tree-icon").children(".layui-icon");

        if (ax[0]) {  //TODO a改为ax

            //TODO 展开节点

            if (!e.hasClass(c) && !e.hasClass(C)) {

                t.spread && t.spread({

                    elem: e,

                    state: a.children.length > 0,

                    data: a

                })

            }

            //TODO 注释掉源码

            /*if (e.hasClass(C)) e.removeClass(C), a.slideUp(200), n.removeClass(u).addClass(h); else if (e.addClass(C), a.slideDown(200), n.addClass(u).removeClass(h), t.accordion) {

                var r = e.siblings("." + s);

                r.removeClass(C), r.children("." + v).slideUp(200), r.find(".layui-tree-icon").children(".layui-icon").removeClass(u).addClass(h)

            }*/

            //TODO 节点展开效果调整添加Begin

            if (e.hasClass(C) && !$(i.target).hasClass("layui-tree-txt")) {

                e.removeClass(C), ax.slideUp(200)

                //修改源码,调整无实线状态时三角图标有动画

                if (!t.showLine) {

                    m.find('span .layui-icon').removeClass(aa).addClass(bb)

                } else {

                    n.removeClass(u).addClass(h)

                }

            } else if (e.addClass(C), ax.slideDown(200), n.addClass(u).removeClass(h), t.accordion) {

                var r = e.siblings("." + s);

                r.removeClass(C), r.children("." + v).slideUp(200), r.find(".layui-tree-icon").children(".layui-icon").removeClass(u).addClass(h)

            } else if (!t.showLine) {

                m.find('span .layui-icon').removeClass(bb).addClass(aa)

            } //TODO 节点展开效果调整添加End

        } else x = "normal"

    })

5:b.prototype.spread 方法修改中,有两处样式添加 aa 、bb:如下所示

需要在tree.js中顶部样式变量处添加。

c = “layui-hide”, d = “layui-disabled”, s = “layui-tree-set”, o = “layui-tree-iconClick”,

    h = "layui-icon-addition", u = "layui-icon-subtraction", p = "layui-tree-entry", f = "layui-tree-main",

    y = "layui-tree-txt", v = "layui-tree-pack", C = "layui-tree-spread", k = "layui-tree-setLineShort",

    m = "layui-tree-showLine", x = "layui-tree-lineExtend" ,

aa = “layui-tree-active”, bb = “layui-tree-iconArrow”, //TODO 添加aa、bb两个样式

步骤2:方案落地
解决问题1:异步加载子节点
通过父节点ID查询子节点数据,绑定tree组件的spread函数,捕捉节点的展开事件,用户点击树节点,根据当前节点ID查询下一级节点,如果children节点有数据,则调用tree的children函数动态地渲染子节点。

//获取部门树

function LoadDeptTree() {

$.ajax({

url: "${ctx}/dept/tree/one-level?parentId=0",

dataType: "json",

async: true,

type: "GET",

success: function (resp) {

  if (resp && resp.msgcode == 0) {

    //无连接线风格

    deptTree =tree.render({

      elem: '#leftTreeArea'

      ,id:'leftTreeArea'

      , data: resp.data

      , showLine: false  //是否开启连接线

      , click: editDept

      , spread: function (obj) {

         if (!obj.state) {

          // 懒加载子节点,异步获取data数据这里根据obj.data.id向后台请求当前节点数据

          $.ajax({

            url: "${ctx}/dept/tree/one-level?parentId="+obj.data.id,

            dataType: "json",

            async: true,

            type: "GET",

            success: function (resp) {

              //当前节点展开,如果下一层有children,则调用树的children方法,动态渲染子节点

              if (resp && resp.msgcode == 0) {

                //第一个参数是树绑定的页面元素ID

                //第二个参数是当前展开节点的ID

                //第三个参数是当前节点子节点的数据(数据格式参照layui的tree组件数据格式)

                tree.children(deptTree.config.id, obj.data.id, resp.data);

              }

            }

          });

        }

      }

    });

  } else {

    alert("加载部门树失败")

  }

},

error:function(XMLHttpRequest, textStatus, error){

  if (error.code == 19) {

    window.location.reload();

  }else{

    alert("加载部门树失败");

  }

}

});

}

解决问题2:父部门添加子部门,局部动态更新视图
选中父部门,动态地为父部门添加一个子部门,添加成功将新增的子部门局部渲染到整体部门树中。下面是添加子部门后,js调用一下我自己的refreshTreeNode函数,函数里有操作layui.tree的局部更新视图的代码,如下:

//重新渲染树节点
function refreshTreeNode(treeNodeId,treeNodeName) {
KaTeX parse error: Expected '}', got 'EOF' at end of input: …ax({ url: "{ctx}/dept/tree/one-level?parentId=“+treeNodeId,
dataType: “json”,
async: true,
type: “GET”,
success: function (resp) {
if (resp && resp.msgcode == 0) {
tree.children(deptTree.config.id, treeNodeId, resp.data);
if (treeNodeName) {
//修改节点名称
$(“div[data-id='”+treeNodeId+”‘]“).find(”.layui-tree-txt").eq(0).html(treeNodeName).attr(“title”,treeNodeName);
}
//光标重新定位到当前节点
$("div[data-id=’“+treeNodeId+”']“).find(”.layui-tree-entry").eq(0).addClass(“layui-table-click”);
}
}
});
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ezageny-Joyous

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值