ExtJs树控件入门———TreePanel

ExtJs树控件入门———TreePanel

本文将为您详细讲解ExtJs树控件的使用,如有不足之处,欢迎您指正,我的QQ:1113905744,

文章中用到的所有代码将在文末附上!

效果图有两种

带复选框与不带复选框的树,在下文中有讲解,注意留意。

注:原始数据中有checked属性则有复选框,没有checked属性则没有复选框

不带复选框

带复选框

调用方式:

详解:

创建一个基类,该类为ExtJs封装好的类,里面包含有:点击父节点选中全部子节点,复选框回显等方法 。直接拿来用就行:

创建树控件 :1. 创建时的类名要以上一步的基类类名为准 2. 数据源(下一步讲解)

创建数据源,树形控件的关键。从后台传来的树形结构的数据,我会分几步做详细讲解,首先上效果图:

接下来为大家详细说明下后台的数据如何整理为嵌套形式的数据,图片如下:

整理树形结构的字段:dept_code 每三位代表一级树,六位为第二级树,依次递增

整理数据方法如下 代码我会放到文章末。

往查到的数据中插入两个属性:leaf,checked ;嵌套的编码:就是你在数据库中定义的三位一级的编码。 下面这个方法只需要修改我在图中标注的那两个地方就可以了

代码:

前台代码:

基类:

Ext.define('Ext.ux.tree.CustomeTreePanel', {

extend : 'Ext.tree.Panel',

rootVisible : false,

useArrows : true, //箭头样式

frame : false, //圆角

header : false,

indeterminateCls : 'x-tree-checkbox-indeterminate',

width : 350,

height : 200,

initComponent:function(){

var me = this;

me.callParent();

},

listeners : {

checkchange : function(node, checked) {

var me = this;

me.setChildrenCheckedStatus(node, checked);

me.updateParentCheckedStatus(node, checked);

},

collapse:function(p){

}

},

setChildrenCheckedStatus : function(node, check) {

var me = this;

var len = node.childNodes.length;

if (len <= 0 || node.get('disabled') === true) {

if (node.get('disabled') === false)

node.set('checked', check);

return node.get('checked') ? 1 : -1;

} else {

var sumcount = 0;

for (var index = 0; index < len; index++) {

var subnode = node.childNodes[index];

subnode.set('checked', check)

sumcount = sumcount+ me.setChildrenCheckedStatus(subnode, check);

}

if (len === Math.abs(sumcount)) {

me.unsetThirdState(node);

node.set('checked', check);

return node.get('checked') ? 1 : -1;

} else {

me.setThirdState(node);

return 0;

}

}

},

updateParentCheckedStatus : function(node, check) {

var me = this;

var nodeparent = node.parentNode;

if (!nodeparent) {

return;

} else {

var len = nodeparent.childNodes.length;

var sumcount = 0;

for (var index = 0; index < len; index++) {

var subnode = nodeparent.childNodes[index];

if (me.isThirdState(subnode)) {

sumcount = sumcount + 0;

} else {

if (subnode.get('checked')) {

sumcount = sumcount + 1;

} else {

sumcount = sumcount - 1;

}

}

}

if (len === Math.abs(sumcount)) {

me.unsetThirdState(nodeparent);

nodeparent.set('checked', check);

} else {

me.setThirdState(nodeparent);

}

me.updateParentCheckedStatus(nodeparent, check);

}

},

isThirdState : function(node) {

return node.get('cls') == this.indeterminateCls;

},

setThirdState : function(node) {

node.set('cls', this.indeterminateCls);

node.set('checked', true);

},

unsetThirdState : function(node) {

node.set('cls', '');

},

getLeafIdSelections : function() {

var me = this;

try {

var tree_selections = me.getView().getChecked(), result = [];

Ext.Array.each(tree_selections, function(rec) {

console.log(rec);

if (rec.get('text')!="Root") {

result.push(rec.get('id')/* ,rec.get('text') */);

}

});

return result;

} catch (e) {

debug('[error in accessPanel getSelections]');

debug(e);

}

},

setSelections : function(codes) {

var ids = codes.split(",");

var me = this;

if (ids[0] && ids[0]['id']) {

ids = Ext.Array.pluck(ids, 'id');

}

me.getRootNode().cascadeBy(

function() {

var currNode = this;

if (currNode.get('leaf')) {

currNode.set('checked',

ids.indexOf(currNode.get('id')) > -1);

me.updateParentCheckedStatus(currNode, ids

.indexOf(currNode.get('id')) > -1);

}

});

},

});

树控件:

bankSysEditTreePanel = Ext.create('Ext.ux.tree.CustomeTreePanel',{

title : "机构列表", //树控件名称

expanded:true, //默认展开树节点 没效果 需要优化一下

rootVisible:false, //是否显示root节点

scrollable: 'y', //滚动条

animScroll:true,//动画效果

store: userBankTreeStore, //调用的数据源

width : '100%',

height : '100%',

border : true,

animCollapse : true,

animate : true,

listeners:{ //监听器

}

});

数据源

var userBankTreeStore;

userBankTreeStore = Ext.create('Ext.data.TreeStore', {

fields: ["bank_name", "bank_id"], //Model

autoLoad : true,

pageSize : 15,

sorters : { //排序

property : 'bank_name',

direction : 'ASC'

},

clearOnLoad : true,

defaultRootId : '-1',

proxy : {

type : 'ajax',

url : getServerHttp() +"/nh-bank/cp/bank/bankList" , //后台接口路径

reader:{

type:'json',

},

},

root:{

expanded:true,

},

autoLoad:false

});

后台代码:

接口方法:

@ApiOperation(value = "树形机构")

@GetMapping("/bankListTo")

public JSONArray bankListTo() {

List> banklist = bankService.allbank(); //查询要整理的原始数据

JSONArray result = JSONArray.parseArray(TreeTools.turnListToTree_bankAdd(banklist)); //整理为嵌套形式

return result;

}

将leaf,checked属性打入原始数据的方法:

public static List> handleTree_bank(List> menuList, boolean isChecked) {

for (Map map : menuList) {

map.put("id", map.get("dept_code"));

map.put("iconCls", map.get("url"));

map.put("text", map.get("bank_name"));

map.put("leaf", true);

if (isChecked) {

map.put("checked", false);

}

}

将数据整理成树结构:

@SuppressWarnings("unchecked")

public static String turnListToTree_bank(List> menuList, boolean isChecked) {

// TODO 转换List为树形结构

menuList = handleTree_bank(menuList, isChecked);

List> nodeList = new ArrayList>();

for (Map node1 : menuList) {

String node1_code = (String) node1.get("dept_code");

String node1_parent_code = node1_code.substring(0, node1_code.length() - 3);

boolean mark = false;

for (Map node2 : menuList) {

String node2_code = (String) node2.get("dept_code");

if (node1_parent_code != null && node1_parent_code.equals(node2_code)) {

mark = true;

if (node2.get("children") == null) {

node2.put("children", new ArrayList>());

}

((List>) node2.get("children")).add(node1);

node2.put("leaf", false);

if (!isChecked) {

node2.put("expanded", true);

}

break;

}

}

if (!mark) {

nodeList.add(node1);

}

}

return JsonUtil.toJson(nodeList);

}

附上一些工作中踩过的坑:

保存树节点:红线标注的方法可以在上文中的基类中找到, 调用(树控件名.方法名)

2.树节点回显:用于回显的数据为逗号分隔的字符串,也就是上文中用于整理嵌套树结构的编码

代码如下:

function myEdit(kid) {

var me = this;

Ext.Ajax.request({

url : getServerHttp() +"/nh-bank/cp/roleAuth/edit_form?kid=" + kid,

success : function(response) {

var json = Ext.JSON.decode(response.responseText);

if(json){

me.showEditPanel(json.result);

}

// 列表树回显数据

window.EditTreePanel.setSelections(json.result.roleAuths); //括号中的数据为逗号分隔的字符串

},

failure : function(response) {

Ext.Msg.alert("提示", "操作失败!");

}

});

}// #myEdit

相关推荐

2026年世界杯巴西队预选赛全程赛程安排及关键对决分析
365完美体育官网入口

2026年世界杯巴西队预选赛全程赛程安排及关键对决分析

📅 07-01 👁️ 8985
WIN10专业版下Edge浏览器设置主页的方法
48365365

WIN10专业版下Edge浏览器设置主页的方法

📅 07-14 👁️ 7767
似鱎鱼的种类
48365365

似鱎鱼的种类

📅 07-24 👁️ 9811
pass学霸笔记有用吗
365完美体育官网入口

pass学霸笔记有用吗

📅 07-03 👁️ 7666
虚拟直播(虚拟场景直播)要怎么做?
bet28365365体育投注

虚拟直播(虚拟场景直播)要怎么做?

📅 06-29 👁️ 6036