文章内不再提供示例,需要查看者请从SVN下载,地址:
http://exttools.googlecode.com/svn/trunk/
效果图:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ext.namespace("QM.ui");
-
- QM.ui.AccordinTreePanel = Ext.extend(Ext.Panel, {
-
-
-
-
-
-
- margins: '5 0 5 5',
- split: true,
- width: 210,
- initComponent: function(){
- Ext.apply(this, {
- layout: 'accordion',
- region: 'west'
- })
- QM.ui.AccordinTreePanel.superclass.initComponent.call(this);
- this.addEvents(
-
-
- 'click',
-
-
- 'afterload');
- if (!this.store) {
- this.store = new Ext.data.JsonStore({
- url: this.url,
- root: this.root,
- fields: ['code', 'name', 'parentcode', 'iconCls', 'href']
- });
- }
- this.store.load({
- callback: this.loadTrees,
- scope: this
- });
- },
- loadTrees: function(records, o, s){
- var pnodes,trees = [],tree;
- this.store.sort('code');
- for (var i = 0; i < records.length; i++) {
- var record = records[i];
- if (!record.get('parentcode')) {
- tree = this.creatTreeConfig(record);
- trees.push(tree);
- pnodes = [];
- pnodes.push(tree.root);
- }
- else {
- var next_record = records[i + 1];
- var isLeaf = !next_record || next_record.get('parentcode') != record.get('code');
- this.addTreeNode(pnodes, record, isLeaf);
- }
- }
- Ext.each(trees,function(tree){
- this.add(tree);
- },this);
- this.fireEvent('afterload', this);
- this.mon(this.el, 'click', this.onClick, this);
- this.doLayout();
- this.store.destroy();
- },
- findNodeById:function(id){
- var node,trees = this.findByType('treepanel',true);
- Ext.each(trees,function(tree){
- node = tree.getNodeById(id);
- return !node;
- });
- return node;
- },
- onClick: function(e, t, o){
- if(Ext.fly(t).hasClass('x-tree-ec-icon')){
- return;
- }
- var el,id,node;
- if (el = e.getTarget('.x-tree-node-el', 3,true)) {
- e.stopEvent();
- id = el.getAttributeNS('ext','tree-node-id');
- node = this.findNodeById(id);
- this.fireEvent('click',node);
- }
- },
- creatTreeConfig: function(record){
- var config = {
- xtype: 'treepanel',
- autoScroll: true,
- rootVisible: false,
- title: record.get('name'),
- iconCls: record.get('iconCls'),
- root: {
- nodeType: 'async',
- expanded: true,
- id: record.get('code'),
- children: []
- }
- };
- return config;
- },
- addTreeNode: function(pnodes, record, isLeaf){
- var len = pnodes.length;
- for (var i = len - 1; i >= 0; i--) {
- if (pnodes[i].id != record.get('parentcode')) {
- pnodes.pop();
- }
- else {
- var parent = pnodes[i].children;
- var node = {
- text: record.get('name'),
- id: record.get('code'),
- iconCls: record.get('iconCls'),
- href: record.get('href'),
- leaf: isLeaf
- };
- if (!isLeaf) {
- node.children = [];
- pnodes.push(node);
- }
- parent.push(node);
- return;
- }
- }
- }
- });
-
- Ext.reg('accTree', QM.ui.AccordinTreePanel);
/**
* 扩展了Panel类,其布局设为accordion,所在区域为west;该组件初始化后会根据配置的url和root向后台发
* 起请求并解析返回的json串,根据parentcode为空的结点生成TreePanel,子节点通过parentcode属性添加为
* 对应结点的子节点,注意此处每个节点的code必须小于父节点并接大于下方的其它结点;
*
* 1.1更新:
* 1.不再需要leaf属性,程序内部判断;
* 2.store用完后即销毁,不再可用;
* 3.修改了结点点击的触发事件,仅注册一次以减少内存占用,该方法传递给监听函数一个Ext.tree.TreeNode对象,
* 可通过node.attributes属性获取结点属性;
* 4.添加了一个findNodeById方法,该方法通过id字符串返回对应Ext.tree.TreeNode对象;
*
* @author [email protected]
* @version 1.1
* @since 2010-5-9
*
*/
Ext.namespace("QM.ui");
QM.ui.AccordinTreePanel = Ext.extend(Ext.Panel, {
/**
* @cfg(url) 发送请求的地址
*/
/**
* @cfg(root) json数组的根字符串
*/
margins: '5 0 5 5',
split: true,
width: 210,
initComponent: function(){
Ext.apply(this, {
layout: 'accordion',
region: 'west'
})
QM.ui.AccordinTreePanel.superclass.initComponent.call(this);
this.addEvents( /**
* @event itemclick 树结点被点击时触发 参数:node 当前结点对象,record 当前结点对应record对象
*/
'click', /**
* @event afterload 菜单项加载完毕后触发
*/
'afterload');
if (!this.store) {
this.store = new Ext.data.JsonStore({
url: this.url,
root: this.root,
fields: ['code', 'name', 'parentcode', 'iconCls', 'href']
});
}
this.store.load({
callback: this.loadTrees,
scope: this
});
},
loadTrees: function(records, o, s){
var pnodes,trees = [],tree;
this.store.sort('code');
for (var i = 0; i < records.length; i++) {
var record = records[i];
if (!record.get('parentcode')) {
tree = this.creatTreeConfig(record);
trees.push(tree);
pnodes = [];
pnodes.push(tree.root);
}
else {
var next_record = records[i + 1];
var isLeaf = !next_record || next_record.get('parentcode') != record.get('code');
this.addTreeNode(pnodes, record, isLeaf);
}
}
Ext.each(trees,function(tree){
this.add(tree);
},this);
this.fireEvent('afterload', this);
this.mon(this.el, 'click', this.onClick, this);
this.doLayout();
this.store.destroy();
},
findNodeById:function(id){
var node,trees = this.findByType('treepanel',true);
Ext.each(trees,function(tree){
node = tree.getNodeById(id);
return !node;//找到的话返回false
});
return node;
},
onClick: function(e, t, o){
if(Ext.fly(t).hasClass('x-tree-ec-icon')){//点击伸展按钮时无视
return;
}
var el,id,node;
if (el = e.getTarget('.x-tree-node-el', 3,true)) {
e.stopEvent();
id = el.getAttributeNS('ext','tree-node-id');
node = this.findNodeById(id);
this.fireEvent('click',node);
}
},
creatTreeConfig: function(record){
var config = {
xtype: 'treepanel',
autoScroll: true,
rootVisible: false,
title: record.get('name'),
iconCls: record.get('iconCls'),
root: {
nodeType: 'async',
expanded: true,
id: record.get('code'),
children: []
}
};
return config;
},
addTreeNode: function(pnodes, record, isLeaf){
var len = pnodes.length;
for (var i = len - 1; i >= 0; i--) {
if (pnodes[i].id != record.get('parentcode')) {
pnodes.pop();
}
else {
var parent = pnodes[i].children;
var node = {
text: record.get('name'),
id: record.get('code'),
iconCls: record.get('iconCls'),
href: record.get('href'),
leaf: isLeaf
};
if (!isLeaf) {
node.children = [];
pnodes.push(node);
}
parent.push(node);
return;
}
}
}
});
Ext.reg('accTree', QM.ui.AccordinTreePanel);
示例js:
- new Ext.Viewport({
- layout: 'border',
- items: [{
- xtype: 'accTree',
- title : '菜单',
- root : 'menus',
- url: 'menu.json',
- listeners:{
- 'click':function(node){
- alert(node.attributes.href);
- }
- }
- }, {
- region: 'center',
- html: 'center'
- }]
- });
- });