当前位置: 代码迷 >> JavaScript >> 依据后台json生成左侧导航菜单
  详细解决方案

依据后台json生成左侧导航菜单

热度:116   发布时间:2012-11-08 08:48:11.0
根据后台json生成左侧导航菜单
文章内不再提供示例,需要查看者请从SVN下载,地址:
http://exttools.googlecode.com/svn/trunk/
效果图:


Js代码
  1. /**?
  2. ?*?扩展了Panel类,其布局设为accordion,所在区域为west;该组件初始化后会根据配置的url和root向后台发?
  3. ?*?起请求并解析返回的json串,根据parentcode为空的结点生成TreePanel,子节点通过parentcode属性添加为?
  4. ?*?对应结点的子节点,注意此处每个节点的code必须小于父节点并接大于下方的其它结点;?
  5. ?*??
  6. ?*?1.1更新:?
  7. ?*?1.不再需要leaf属性,程序内部判断;?
  8. ?*?2.store用完后即销毁,不再可用;?
  9. ?*?3.修改了结点点击的触发事件,仅注册一次以减少内存占用,该方法传递给监听函数一个Ext.tree.TreeNode对象,?
  10. ?*?可通过node.attributes属性获取结点属性;?
  11. ?*?4.添加了一个findNodeById方法,该方法通过id字符串返回对应Ext.tree.TreeNode对象;?
  12. ?*??
  13. ?*?@author?chemzqm@gmail.com?
  14. ?*?@version?1.1?
  15. ?*?@since?2010-5-9?
  16. ?*?
  17. ?*/??
  18. Ext.namespace("QM.ui");??
  19. ??
  20. QM.ui.AccordinTreePanel?=?Ext.extend(Ext.Panel,?{??
  21. ????/**?
  22. ?????*?@cfg(url)?发送请求的地址?
  23. ?????*/??
  24. ????/**?
  25. ?????*?@cfg(root)?json数组的根字符串?
  26. ?????*/??
  27. ????margins:?'5?0?5?5',??
  28. ????split:?true,??
  29. ????width:?210,??
  30. ????initComponent:?function(){??
  31. ????????Ext.apply(this,?{??
  32. ????????????layout:?'accordion',??
  33. ????????????region:?'west'??
  34. ????????})??
  35. ????????QM.ui.AccordinTreePanel.superclass.initComponent.call(this);??
  36. ????????this.addEvents(????????/**?
  37. ?????????*?@event?itemclick??树结点被点击时触发??参数:node?当前结点对象,record?当前结点对应record对象?
  38. ?????????*/??
  39. ????????'click',????????/**?
  40. ?????????*?@event?afterload?菜单项加载完毕后触发?
  41. ?????????*/??
  42. ????????'afterload');??
  43. ????????if?(!this.store)?{??
  44. ????????????this.store?=?new?Ext.data.JsonStore({??
  45. ????????????????url:?this.url,??
  46. ????????????????root:?this.root,??
  47. ????????????????fields:?['code',?'name',?'parentcode',?'iconCls',?'href']??
  48. ????????????});??
  49. ????????}??
  50. ????????this.store.load({??
  51. ????????????callback:?this.loadTrees,??
  52. ????????????scope:?this??
  53. ????????});??
  54. ????},??
  55. ????loadTrees:?function(records,?o,?s){??
  56. ????????var?pnodes,trees?=?[],tree;??
  57. ????????this.store.sort('code');??
  58. ????????for?(var?i?=?0;?i?<?records.length;?i++)?{??
  59. ????????????var?record?=?records[i];??
  60. ????????????if?(!record.get('parentcode'))?{??
  61. ????????????????tree?=?this.creatTreeConfig(record);??
  62. ????????????????trees.push(tree);??
  63. ????????????????pnodes?=?[];??
  64. ????????????????pnodes.push(tree.root);??
  65. ????????????}??
  66. ????????????else?{??
  67. ????????????????var?next_record?=?records[i?+?1];??
  68. ????????????????var?isLeaf?=?!next_record?||?next_record.get('parentcode')?!=?record.get('code');??
  69. ????????????????this.addTreeNode(pnodes,?record,?isLeaf);??
  70. ????????????}??
  71. ????????}??
  72. ????????Ext.each(trees,function(tree){??
  73. ????????????this.add(tree);??
  74. ????????},this);??
  75. ????????this.fireEvent('afterload',?this);??
  76. ????????this.mon(this.el,?'click',?this.onClick,?this);??
  77. ????????this.doLayout();??
  78. ????????this.store.destroy();??
  79. ????},??
  80. ????findNodeById:function(id){??
  81. ????????var?node,trees?=?this.findByType('treepanel',true);??
  82. ????????Ext.each(trees,function(tree){??
  83. ????????????node?=?tree.getNodeById(id);??
  84. ????????????return?!node;//找到的话返回false??
  85. ????????});??
  86. ????????return?node;??
  87. ????},??
  88. ????onClick:?function(e,?t,?o){??
  89. ????????if(Ext.fly(t).hasClass('x-tree-ec-icon')){//点击伸展按钮时无视??
  90. ????????????return;??
  91. ????????}??
  92. ????????var?el,id,node;?????
  93. ????????if?(el?=?e.getTarget('.x-tree-node-el',?3,true))?{??
  94. ????????????e.stopEvent();??
  95. ????????????id?=?el.getAttributeNS('ext','tree-node-id');??
  96. ????????????node?=?this.findNodeById(id);??
  97. ????????????this.fireEvent('click',node);??
  98. ????????}??
  99. ????},??
  100. ????creatTreeConfig:?function(record){??
  101. ????????var?config?=?{??
  102. ????????????xtype:?'treepanel',??
  103. ????????????autoScroll:?true,??
  104. ????????????rootVisible:?false,??
  105. ????????????title:?record.get('name'),??
  106. ????????????iconCls:?record.get('iconCls'),??
  107. ????????????root:?{??
  108. ????????????????nodeType:?'async',??
  109. ????????????????expanded:?true,??
  110. ????????????????id:?record.get('code'),??
  111. ????????????????children:?[]??
  112. ????????????}??
  113. ????????};??
  114. ????????return?config;??
  115. ????},??
  116. ????addTreeNode:?function(pnodes,?record,?isLeaf){??
  117. ????????var?len?=?pnodes.length;??
  118. ????????for?(var?i?=?len?-?1;?i?>=?0;?i--)?{??
  119. ????????????if?(pnodes[i].id?!=?record.get('parentcode'))?{??
  120. ????????????????pnodes.pop();??
  121. ????????????}??
  122. ????????????else?{??
  123. ????????????????var?parent?=?pnodes[i].children;??
  124. ????????????????var?node?=?{??
  125. ????????????????????text:?record.get('name'),??
  126. ????????????????????id:?record.get('code'),??
  127. ????????????????????iconCls:?record.get('iconCls'),??
  128. ????????????????????href:?record.get('href'),??
  129. ????????????????????leaf:?isLeaf??
  130. ????????????????};??
  131. ????????????????if?(!isLeaf)?{??
  132. ????????????????????node.children?=?[];??
  133. ????????????????????pnodes.push(node);??
  134. ????????????????}??
  135. ????????????????parent.push(node);??
  136. ????????????????return;??
  137. ????????????}??
  138. ????????}??
  139. ????}??
  140. });??
  141. ??
  142. 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 chemzqm@gmail.com
 * @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:
Js代码
  1. new?Ext.Viewport({??
  2. ????????????????????layout:?'border',??
  3. ????????????????????items:?[{??
  4. ????????????????????????xtype:?'accTree',??
  5. ????????????????????????title?:?'菜单',??
  6. ????????????????????????root?:?'menus',//必须要配??
  7. ????????????????????????url:?'menu.json',//必须要配??
  8. ????????????????????????listeners:{??
  9. ????????????????????????????'click':function(node){??
  10. ????????????????????????????????alert(node.attributes.href);??
  11. ????????????????????????????}??
  12. ????????????????????????}??
  13. ????????????????????},?{??
  14. ????????????????????????region:?'center',??
  15. ????????????????????????html:?'center'??
  16. ????????????????????}]??
  17. ????????????????});??
  18. ????????????});??
  相关解决方案