bootstrap-treeview是一款非常不错的树组件,但是官方提供的版本中只有静态的,也就是说我们在使用的时候必须一次性从服务端查询出所有节点,包括所有根节点和叶节点。如果是简单的数据这样是非常方便的,但在企业级项目中,往往树节点既多又深,一次性全部加载的话不但会影响性能,而且会导致数据不同步。故而,笔者在官方提供的版本的基础上,开发了懒加载功能,下面先来看看实现后的效果。
VID_20231222_143530
可以看到每点展开一次根节点,右侧就会访问一次服务端,动态加载出其下的子节点,这样可以大大提高性能,还能防止由于不同步造成的数据不准确问题。下面附上重点代码,也是懒加载的核心代码:
/**
* 类功能描述: 该组件是bootstrap_treeview.js的扩展组件,所以要使用该组件,必须同时引入bootstrap_treeview.js。该组件提供单个树和多个树的异步加载功能。
* @author 西山水壶
*
* 一、单个树使用说明
*
* 1、直接使用前台数据作为节点,不访问后台,代码如下:
* var defaultData = [
* {
* text: 'Parent 1',
* nodes: [
* {
* text: 'Child 1',
* nodes: [
* {
* text: 'Grandchild 1',
* },
* {
* text: 'Grandchild 2',
* }
* ]
* },
* {
* text: 'Child 2',
* }
* ]
* },
* {
* text: 'Parent 2',
* },
* {
* text: 'Parent 3',
* }
* ];
*
* $('#treeview1').treeview({
* data: defaultData
* });
*
* 以上代码defaultData是树的节点数据,treeview1是页面中的div。
*
* 2、使用单个表的后台数据作为节点,并且该表中能通过父ID字段体现树的层级关系,点击某个父节点时异步加载子节点,代码如下:
*
* Bhl.plugin.BootStrapTree.initTree({
*
* treeViewId : "indexsys_zbjk_treeview", //展示树的页面id
*
* tableName : "BI_ECO_INDEX_SYS_COL", //存放树节点的数据库表名
*
* idFieldName : "ID_", //id字段名
*
* parentIdFieldName : "PID_", //父Id字段名
*
* codeFieldName : "CODE_", //code字段名(非必须)
*
* nameFieldName : "NAME_", //树节点文本字段名
*
* otherFieldName : "TYPE_,FUN_", //其它字段名(非必须)
*
* orderBySql : " ORDER BY CODE_ ", //排序条件(非必须)
*
* filterParamRoot : { //该参数为初始化树的根节点时的查询过滤条件(非必须)
* searchCondition:"以and开头的sql条件语句" //searchCondition属性名是组件默认的,不能更改
* },
*
* filterParamChildren : { //该参数为展开树的根节点加载子节点时的查询过滤条件(非必须)
* searchConditionByExpand:"以and开头的sql条件语句" //searchConditionByExpand属性名是组件默认的,不能更改
* }
* });
*
* 以上代码为初始化该扩展组件属性的代码,其中所有属性都不是官方提供的,并且每个属性的值只是假设值,实际操作中要替换成自己需要的值,后台的Controller和Adapter都使用系统默认的,
* 执行上面的代码后并不能展示树,要展示树还要执行以下代码:
*
* var param={
*
* multiSelect : false, //是否可以多选
*
* onNodeSelected : function(event, node) { //选中树节点触发的事件
* do something;
* },
*
* onNodeUnselected : function(event, node) { //取消选中树节点触发的事件
* do something;
* },
*
* showCheckboxOnlyChildren : false, //是否只在子节点显示复选框(非官方)
*
* showCheckboxCondition : function(node){ //满足一定条件才显示复选框,满足返回true,否则返回false(非官方)
* do something;
* }
*
* showCheckbox : true, //是否显示复选框
*
* onNodeChecked : function(event, node) { //选中复选框触发的事件
* do something;
* },
*
* onNodeUnchecked : function(event, node) { //取消选中复选框触发的事件
* do something;
* }
* }
*
* 以上代码中的属性为官方提供,只不过这几个是常用的,其他不常用的还有很多,请参看官方手册,其中showCheckboxOnlyChildren属性为非官方的,
* 是作者后来加到bootstrap_treeview.js中的,原版的bootstrap_treeview.js没有这个属性。
*
* Bhl.plugin.BootStrapTree.buildTree(param); //执行这行代码才真正把树显示出来
*
* 3、使用自己的Controller作为后台,点击某个父节点时异步加载子节点,代码如下:
*
* Bhl.plugin.BootStrapTree.initTree({
*
* treeViewId : "indexsys_zbjk_treeview", //展示树的页面id
*
* jsonUrl : "bi/companyinfo/cdes/getGroupTreeJson", //自己的Controller
*
* filterParamRoot : { //该参数为初始化树的根节点时的查询过滤条件(非必须),里面的属性为自己实际需要的属性
* year : "2016",
* month : "05",
* 其它属性...
* },
*
* filterParamChildren : { //该参数为展开树的根节点加载子节点时的查询过滤条件(非必须)
* year : "2016",
* month : "05",
* 其它属性...
* },
*
* beforeOnClick : function(node){ //展开子节点前触发的事件
* do something;
* }
* });
*
* 自己的Controller返回的json格式应该是以下格式:
*
* [
* {
* text : 'Parent 1', //要显示的文本
* nodes : [], //nodes代表该节点下还有子节点
* 其他属性...
* },
* {
* text : 'Parent 2',
* 其他属性...
* },
* {
* text : 'Parent 3',
* 其他属性...
* }
* ]
*
* 自己的Controller返回的json应至少包含text属性,一般情况下还应包含id属性,如果该节点下有子节点还应包含nodes属性,但是nodes属性一定是个空数组,在点击时候才加载子节点。
* 需要注意的是,该组件只允许设置一个Controller,也就是说加载根节点和点击根节点异步加载子节点都使用这个Controller,所以该组件提供了filterParamRoot和
* filterParamChildren属性以便于加载不同节点的时候传入不同的过滤参数。但是很多时候需要在展开子节点的时候才能确定传什么参数,比如父id,该组件的beforeOnClick事件能满足
* 这个需求,例如在点击父节点的时候传入父id,应该按照以下方式设置:
*
* beforeOnClick : function(node){ //展开子节点前触发的事件
* Bhl.plugin.BootStrapTree.filterParamChildren={
* pid:node.id
* }
* }
*
* 以上代码node为节点对象,pid和node.id在实际使用时应该替换成自己需要的参数
*
*
* 二、多个树使用说明
*
* 1、直接使用前台数据作为节点,不访问后台,代码如下:
* var defaultData1 = [
* {
* text: 'Parent 1',
* nodes: [
* {
* text: 'Child 1',
* nodes: [
* {
* text: 'Grandchild 1',
* },
* {
* text: 'Grandchild 2',
* }
* ]
* },
* {
* text: 'Child 2',
* }
* ]
* },
* {
* text: 'Parent 2',
* },
* {
* text: 'Parent 3',
* }
* ];
*
* $('#treeview1').treeview({
* data: defaultData1
* });
*
* var defaultData2 = [
* {
* text: 'Parent 21',
* nodes: [
* {
* text: 'Child 21',
* nodes: [
* {
* text: 'Grandchild 21',
* },
* {
* text: 'Grandchild 22',
* }
* ]
* },
* {
* text: 'Child 22',
* }
* ]
* },
* {
* text: 'Parent 22',
* },
* {
* text: 'Parent 23',
* }
* ];
*
* $('#treeview2').treeview({
* data: defaultData2
* });
*
* 2、使用单个表的后台数据作为节点,并且该表中能通过父ID字段体现树的层级关系,点击某个父节点时异步加载子节点,代码如下:
*
* Bhl.plugin.BootStrapTree.initTree({
*
* treeViewId : ["indexsys_zbjk_treeview1","indexsys_zbjk_treeview2"], //展示树的页面id
*
* tableName : ["BI_ECO_INDEX_SYS_COL1","BI_ECO_INDEX_SYS_COL2"], //存放树节点的数据库表名
*
* idFieldName : ["ID1_","ID2_"], //id字段名
*
* parentIdFieldName : ["PID1_","PID2_"], //父Id字段名
*
* codeFieldName : ["CODE1_","CODE2_"], //code字段名(非必须)
*
* nameFieldName : ["NAME1_","NAME2_"], //树节点文本字段名
*
* otherFieldName : ["TYPE1_,FUN1_","TYPE2_,FUN2_"], //其它字段名(非必须)
*
* orderBySql : ["ORDER BY CODE1_","ORDER BY CODE2_"], //排序条件(非必须)
*
* filterParamRoot : [ //该参数为初始化树的根节点时的查询过滤条件(非必须)
* {
* searchCondition:"以and开头的sql条件语句" //searchCondition属性名是组件默认的,不能更改
* },
* {
* searchCondition:"以and开头的sql条件语句" //searchCondition属性名是组件默认的,不能更改
* }
* ],
*
* filterParamChildren : [ //该参数为展开树的根节点加载子节点时的查询过滤条件(非必须)
* {
* searchConditionByExpand:"以and开头的sql条件语句" //searchConditionByExpand属性名是组件默认的,不能更改
* },
* {
* searchConditionByExpand:"以and开头的sql条件语句" //searchConditionByExpand属性名是组件默认的,不能更改
* }
* ],
* });
*
* 以上代码为在同一页面中构建两个树的代码,所有属性都是数组形式,每个属性的顺序一定要统一,除了treeViewId属性外,如果其它属性多个树的值都一样,那么也可以写成非数组形式,例如两个表的ID
* 字段名一样,那么可以写成如下形式:
*
* idFieldName:"ID_"
*
* 当然也可以写成如下形式:
*
* idFieldName:["ID_","ID_"]
*
* 如果根节点过滤参数一样,可以写成如下形式:
*
* filterParamRoot : {
* searchCondition:"以and开头的sql条件语句"
* }
*
* 其它字段以此类推。
*
* 执行上面的代码后并不能展示树,要展示树还要执行以下代码:
*
* var param={
*
* showCheckboxOnlyChildren : [false,true],
*
* showCheckboxCondition : [
*
* function(node) {
* do something;
* },
*
* function(node) {
* do something;
* }
*
* ],
*
* showCheckbox : [false,true],
*
* onNodeChecked : [
*
* function(event, node) {
* do something;
* },
*
* function(event, node) {
* do something;
* }
*
* ],
*
* onNodeUnchecked : [
*
* function(event, node) {
* do something;
* },
*
* function(event, node) {
* do something;
* }
*
* ],
*
* onNodeSelected : [
*
* function(event, node) {
* do something;
* },
*
* function(event, node) {
* do something;
* }
*
* ],
* }
*
* 注意:如果是多个树,以上param中的属性必须为数组形式。
*
* Bhl.plugin.BootStrapTree.buildTree(param);
*
* 3、使用自己的Controller作为后台,点击某个父节点时异步加载子节点,代码与上面类似,需要注意的是以下代码:
*
* beforeOnClick : [
* function(node){
* Bhl.plugin.BootStrapTree.filterParamChildren[0]={
* pid:node.id
* }
* },
* function(node){
* Bhl.plugin.BootStrapTree.filterParamChildren[1]={
* pid:node.id
* }
* }
* ]
*
* 以上代码中要注意把Bhl.plugin.BootStrapTree.filterParamChildren写成数组形式,其他函数数组也需要注意。
*/
$.bhl_ns("Bhl.plugin.BootStrapTree",function(){
Bhl.plugin.BootStrapTree={
/**
* 项目上下文
*/
context:'',
/**
* 获取数据的后台
*/
jsonUrl:"bi/bootstrap/tree/getTreeJsonData",
isAsync:0,
/**
* 展示树的页面id
*/
treeViewId:null,
/**
* 左侧导航栏id
*/
sidebarId:"frame-main-sidebar",
/**
* 鼠标放到树节点上的提示信息
*/
reminderDiv:"<div id='bootStrapTree_reminderDiv' style='z-index:999;font-family:\"微软雅黑\";display:none;position:fixed;top:100px;left:300px;background-color:#FFEE99;color:black;'></div>",
/**
* 加载节点时的等待信息
*/
loadWaitDiv:"<div id='bootStrapTree_loadWaitDiv' style='z-index:999;font-family:\"微软雅黑\";display:none;position:absolute;top:100px;left:300px;background-color:#CCCCFF;'></div>",
/**
* 每个节点最多显示的字的个数
*/
characterNum:13,
/**
* 树的实例
*/
treeObj:null,
/**
* 获取数据的valueList
*/
key:"bi_bootstrap_tree_Adapter",
/**
* 存放树节点的数据库表名
*/
tableName:null,
/**
* id字段名
*/
idFieldName:null,
/**
* parentId字段名
*/
parentIdFieldName:null,
/**
* code字段名
*/
codeFieldName:null,
/**
* 其它字段名
*/
otherFieldName:null,
/**
* 树节点文本字段名
*/
nameFieldName:null,
/**
* 根节点的过滤参数
*/
filterParamRoot:null,
/**
* 子节点的过滤参数
*/
filterParamChildren:null,
/**
* 排序条件
*/
orderBySql:null,
/**
* 鼠标点击加号时的x坐标
*/
pageX:null,
/**
* 鼠标点击加号时的y坐标
*/
pageY:null,
/**
* 加载子节点后的回调函数
*/
getChildrenCallBack:null,
/**
* 初始化树
*/
initTree:function(data){
$.extend(true,Bhl.plugin.BootStrapTree,data);
var me=this;
if(me.treeViewId.constructor===Array){
me.jsonUrl=me.initMulityTree(me.jsonUrl);
me.key=me.initMulityTree(me.key);
me.tableName=me.initMulityTree(me.tableName);
me.idFieldName=me.initMulityTree(me.idFieldName);
me.parentIdFieldName=me.initMulityTree(me.parentIdFieldName);
me.codeFieldName=me.initMulityTree(me.codeFieldName);
me.otherFieldName=me.initMulityTree(me.otherFieldName);
me.nameFieldName=me.initMulityTree(me.nameFieldName);
me.filterParamChildren=me.initMulityTree(me.filterParamChildren);
me.filterParamRoot=me.initMulityTree(me.filterParamRoot);
me.orderBySql=me.initMulityTree(me.orderBySql);
}
},
/**
* 处理多个树
*/
initMulityTree:function(obj){
var me=this;
if (obj==null) {
obj=new Array();
$.each(me.treeViewId,function(i,treeViewId){
obj.push(null);
});
}else if(obj.constructor!==Array){
var val=obj;
obj=new Array();
$.each(me.treeViewId,function(i,treeViewId){
obj.push(val);
});
}
return obj;
},
/**
* 获取数据
*/
getTreeData:function(param,callBack,async){
if (!!param.otherFieldName) {
var otherFieldNames=param.otherFieldName.split(","),
str="";
$.each(otherFieldNames,function(i,obj){
str+="A."+obj+" as "+obj+",";
});
param.otherFields=str;
}
$.ajax({
type: "GET",
async:this.isAsync==1? false :async ,
url: '/'+param.jsonUrl,
data: param,
beforeSend:function(req){
var $loadWaitDiv=$(Bhl.plugin.BootStrapTree.loadWaitDiv);
if ($("#bootStrapTree_loadWaitDiv").length<1) {
$loadWaitDiv.appendTo($('body'));
}
$loadWaitDiv=$("#bootStrapTree_loadWaitDiv");
$loadWaitDiv.html(" 正在加载请稍候... ");
$loadWaitDiv.css("top",Bhl.plugin.BootStrapTree.pageY).css("left",Bhl.plugin.BootStrapTree.pageX+20);
$("#bootStrapTree_loadWaitDiv").show();
},
success: callBack,
error:function(e){
Bhl.plugin.BootStrapTree.treeObj=null;
},
complete:function(){
$("#bootStrapTree_loadWaitDiv").hide();
}
});
},
/**
* 处理节点数据
* data 要处理的数据
* level 节点所在的层级
*/
disposeTreeData:function(data,level){
//加1是为了保证节点前面有加号的时候不会折行
var num=Bhl.plugin.BootStrapTree.characterNum-(level==0?0:level+1);
$.each(data,function(){
this.level=level;
if (!!this.value) {
this.text=this.value;
if ( this.value&&this.value.length>num ) {
this.text=this.value;
}else{
this.value=null;
}
}else{
if ( this.text&&this.text.length>num ) {
this.value=this.text;
this.text=this.value;
}
}
if (!!this.nodes) {
Bhl.plugin.BootStrapTree.disposeTreeData(this.nodes,level+1);
}
});
},
/**
* 注册节点鼠标划过事件
*/
registerTreeMouseover:function($treeView,treeObj){
function move(target, event){
var $reminderDiv=$(Bhl.plugin.BootStrapTree.reminderDiv);
var $event=$(target);
if ($("#bootStrapTree_reminderDiv").length<1) {
$reminderDiv.appendTo($event);
}
$reminderDiv=$("#bootStrapTree_reminderDiv");
$reminderDiv.css("top",event.pageY+10).css("left",event.pageX+10);
}
$treeView.find("li").off('mouseover');
$treeView.find("li").on('mouseover', $.proxy(function(event){
var node2=treeObj.findNode($(this));
if(!!node2.value){
move($(this), event);
var $reminderDiv=$("#bootStrapTree_reminderDiv");
$reminderDiv.html(" "+node2.value+" ");
$("#bootStrapTree_reminderDiv").show();
}
})).on('mouseout', function(event){
$("#bootStrapTree_reminderDiv").hide();
move(this, event);
}).on('mousemove', function(event){
move(this, event);
});
},
/**
* 展开节点之前执行
*/
registerSidebarClick:function($treeView,treeObj){
$("#"+Bhl.plugin.BootStrapTree.sidebarId).on('click', function(event){
if (!treeObj) {
return;
}
setTimeout(function(){
if ($treeView.width()<270) {
Bhl.plugin.BootStrapTree.characterNum=10;
}else if($treeView.width()<350){
Bhl.plugin.BootStrapTree.characterNum=13;
}else if($treeView.width()<450){
Bhl.plugin.BootStrapTree.characterNum=16;
}else{
Bhl.plugin.BootStrapTree.characterNum=20;
}
if (!!treeObj) {
var nodes=treeObj.tree;
Bhl.plugin.BootStrapTree.disposeTreeData(nodes,0);
treeObj.render();
Bhl.plugin.BootStrapTree.registerTreeMouseover($treeView,treeObj);
}
},800)
});
},
/**
* 展开节点之前执行
*/
beforeOnClick:function(node){
},
/**
* 查找节点
*/
findNodes:function(treeObj,option){
var nodes=$.grep(treeObj.nodes, function (node) {
var b=true;
$.each(option,function(name,value){
if (node[name]!==value) {
b=false;
}
});
return b;
});
return nodes;
},
/**
* 构建树
*/
buildTree:function(treeData,userCallBack){
if(Bhl.plugin.BootStrapTree.treeViewId.constructor===Array){
Bhl.plugin.BootStrapTree.treeObj=new Array();
$.each(Bhl.plugin.BootStrapTree.treeViewId,function(i,treeViewId){
var $treeView=$('#'+treeViewId),jsonUrl;
$treeView.empty();
var param={
tableName:Bhl.plugin.BootStrapTree.tableName[i],
idFieldName:Bhl.plugin.BootStrapTree.idFieldName[i],
parentIdFieldName:Bhl.plugin.BootStrapTree.parentIdFieldName[i],
nameFieldName:Bhl.plugin.BootStrapTree.nameFieldName[i],
codeFieldName:Bhl.plugin.BootStrapTree.codeFieldName[i],
orderBySql:Bhl.plugin.BootStrapTree.orderBySql[i],
jsonUrl:Bhl.plugin.BootStrapTree.jsonUrl[i],
otherFieldName:Bhl.plugin.BootStrapTree.otherFieldName[i],
key:Bhl.plugin.BootStrapTree.key[i],
};
var callBack=function(obj){
Bhl.plugin.BootStrapTree.disposeTreeData(obj.data,0);
var treeParam={
levels: 0,
showBorder: false,
onClick: function(event) {
var $target=$(event.target);
var treeObj=Bhl.plugin.BootStrapTree.treeObj[i];
if ($target.attr("class").indexOf("expand-icon")>-1) {
Bhl.plugin.BootStrapTree.pageX=event.pageX;
Bhl.plugin.BootStrapTree.pageY=event.pageY;
var node2=treeObj.findNode($target);
Bhl.plugin.BootStrapTree.beforeOnClick[i](node2);
if(!!node2.nodes&&node2.nodes.length==0){
var childParam={
parentId:node2.id
}
$.extend(true,childParam,param);
var level=$target.prevAll("span[class='indent dd-nodrag']").length+1;
$.extend(true,childParam,Bhl.plugin.BootStrapTree.filterParamChildren[i]);
Bhl.plugin.BootStrapTree.getTreeData(childParam,function(obj){
Bhl.plugin.BootStrapTree.disposeTreeData(obj.data,level);
$.extend(true,node2.nodes,obj.data)
treeObj.setInitialStates({ nodes: [node2] }, 0);
treeObj.clickHandler(event);
Bhl.plugin.BootStrapTree.registerTreeMouseover($treeView,treeObj);
if (Bhl.plugin.BootStrapTree.getChildrenCallBack!=null) {
Bhl.plugin.BootStrapTree.getChildrenCallBack[i].call(this,obj.data);
}
},true);
}else{
treeObj.clickHandler(event);
}
}
else{
treeObj.clickHandler(event);
}
Bhl.plugin.BootStrapTree.registerTreeMouseover($treeView,treeObj);
},
data: obj.data
}
var p={};
$.each(treeData,function(name,value){
p[name]=value[i];
});
$.extend(true,treeParam,p);
$treeView.treeview(treeParam);
var treeObj=$treeView.data('treeview');
Bhl.plugin.BootStrapTree.treeObj.push(treeObj);
$treeView.off('click');
$treeView.on('click', $.proxy(treeParam.onClick,treeObj));
Bhl.plugin.BootStrapTree.registerSidebarClick($treeView,treeObj);
Bhl.plugin.BootStrapTree.registerTreeMouseover($treeView,treeObj);
if (Bhl.plugin.BootStrapTree.getChildrenCallBack!=null) {
Bhl.plugin.BootStrapTree.getChildrenCallBack[i].call(this,obj.data);
}
if($.isFunction(userCallBack)){
userCallBack.call(this,obj.data);
}
}
var rootParam={
noParentId:true
}
$.extend(true,rootParam,param);
$.extend(true,rootParam,Bhl.plugin.BootStrapTree.filterParamRoot[i]);
Bhl.plugin.BootStrapTree.getTreeData(rootParam,callBack,false);
});
}else{
var $treeView=$('#'+Bhl.plugin.BootStrapTree.treeViewId);
$treeView.empty();
var param={
tableName:this.tableName,
idFieldName:this.idFieldName,
parentIdFieldName:this.parentIdFieldName,
nameFieldName:this.nameFieldName,
codeFieldName:this.codeFieldName,
jsonUrl:this.jsonUrl,
otherFieldName:this.otherFieldName,
orderBySql:this.orderBySql,
key:this.key
};
var callBack=function(obj){
Bhl.plugin.BootStrapTree.disposeTreeData(obj.data,0);
var treeParam={
levels: 0,
showBorder: false,
onClick: function(event) {
var $target=$(event.target);
if ($target.attr("class").indexOf("expand-icon")>-1) {
var node2=Bhl.plugin.BootStrapTree.treeObj.findNode($target);
Bhl.plugin.BootStrapTree.beforeOnClick(node2);
if(!!node2.nodes&&node2.nodes.length==0){
var childParam={
parentId:node2.id
}
$.extend(true,childParam,param);
$.extend(true,childParam,Bhl.plugin.BootStrapTree.filterParamChildren);
var level=$target.prevAll("span[class='indent dd-nodrag']").length+1;
Bhl.plugin.BootStrapTree.getTreeData(childParam,function(obj){
Bhl.plugin.BootStrapTree.disposeTreeData(obj.data,level);
$.extend(true,node2.nodes,obj.data)
Bhl.plugin.BootStrapTree.treeObj.setInitialStates({ nodes: [node2] }, 0);
Bhl.plugin.BootStrapTree.treeObj.clickHandler(event);
Bhl.plugin.BootStrapTree.registerTreeMouseover($treeView,Bhl.plugin.BootStrapTree.treeObj);
if (Bhl.plugin.BootStrapTree.getChildrenCallBack!=null) {
Bhl.plugin.BootStrapTree.getChildrenCallBack.call(this,obj.data);
}
},true);
}else{
Bhl.plugin.BootStrapTree.treeObj.clickHandler(event);
}
}
else{
Bhl.plugin.BootStrapTree.treeObj.clickHandler(event);
}
Bhl.plugin.BootStrapTree.registerTreeMouseover($treeView,Bhl.plugin.BootStrapTree.treeObj);
},
data: obj.data
}
$.extend(true,treeParam,treeData);
$treeView.treeview(treeParam);
Bhl.plugin.BootStrapTree.treeObj=$treeView.data('treeview');
$treeView.off('click');
$treeView.on('click', $.proxy(treeParam.onClick, Bhl.plugin.BootStrapTree.treeObj));
Bhl.plugin.BootStrapTree.registerSidebarClick($treeView,Bhl.plugin.BootStrapTree.treeObj);
Bhl.plugin.BootStrapTree.registerTreeMouseover($treeView,Bhl.plugin.BootStrapTree.treeObj);
if (Bhl.plugin.BootStrapTree.getChildrenCallBack!=null) {
Bhl.plugin.BootStrapTree.getChildrenCallBack.call(this,obj.data);
}
if($.isFunction(userCallBack)){
userCallBack.call(this,obj.data);
}
}
var rootParam={
noParentId:true,
}
$.extend(true,rootParam,param);
$.extend(true,rootParam,this.filterParamRoot);
this.getTreeData(rootParam,callBack,true);
}
}
}
});
该代码不但支持单棵树,还支持多棵树,为了大家方便测试,同时附上整个代码包,里面包括所需的js和css文件
链接如下: