频道栏目
首页 > 程序开发 > web前端 > JavaScript > 正文
Extjs4快速上手四——实现菜单
2013-05-05 09:41:17           
收藏   我要投稿

本次将主要讲Extjs树形菜单的实现。在很多系统里边,树形菜单被广泛应用,主要因为其有清晰的层次结构。记得最早见到的树形菜单是通过<ul><li>实现的,非常简单。之后用C#的现成控件拖拽了一个,当时还沾沾自喜。再后来在学习师兄的一个通用后台代码时,看到了梅花雪,当时感觉太强大了,每个节点都可以存在数据库,并且能够进行自定义。之后接触到一些UI库之后,更是见到了更强大的树形菜单。

  或许实现一个简单的树形菜单对于不少人并非难事,但是想要实现一个功能比较完善的确要花不少功夫。好在目前有很多现成的供我们使用,而Extjs也提供了功能丰富的树形菜单。本次我们就来讲最简单的一种:Ext.tree.Panel。

  正如之前讲到的,我们在实现一个Extjs组件时,应该按照如下的步骤:

 

  以下就是各部分的代码实现:

//modelExt.define('et.model.Menu', {
    extend: 'Ext.data.Model',
    fields:  ['mid', 'text','cls','columns','url','expanded','optype']
});//或许你看到这些字段和下边json数据并不对应,这个并不重要,这里边有几个是我自己拓展的,只是没用到,只要几个关键的字段设置即可,下边会有介绍。
//storeExt.define('et.store.Menus',{
    extend: 'Ext.data.TreeStore',
    requires: 'et.model.Menu',
     model: 'et.model.Menu',
     autoLoad: true,            //设置自动加载,在打开页面的时候数据就自动加载
     proxy: {
        type: 'ajax',
        url: 'data/manager.json',
        reader: {
            type: 'json',
            successProperty: 'success'
        }
    }
});
//viewExt.define('et.view.Menu',{
    extend: 'Ext.tree.Panel',
    alias: 'widget.sxptmenu',
    requires:['et.store.Menus'],
    initComponent : function(){
        Ext.apply(this,{
            id: 'menu-panel',
            title: '系统菜单',
            iconCls:'icon-menu',
            margins : '0 0 -1 1',
            region:'west',
            border : false,
            enableDD : false,
            split: true,
            width : 212,
            minSize : 130,
            maxSize : 300,
            rootVisible: false,
            containerScroll : true,
            collapsible : true,
            autoScroll: false,
            store:Ext.create('et.store.Menus')
        });
        this.callParent(arguments);
    }
});
//controllerExt.define('et.controller.Menu',{
    extend: 'Ext.app.Controller',
    stores: ['Menus'], 
    models: ['Menu'], 
    views: ['Menu'], 
    init: function () { 
    //初始化部分,下面是部分是给菜单绑定单击事件,接下来会用,这里先注释 
        this.control({ 
            'sxptmenu': { 
              itemmousedown: this.loadMenu
          }
          });
    },
    loadMenu:function(selModel, record){     //加载菜单项对应panel,首先判断是不是叶子结点,是的话判断当前该panel是否已经创建,已创建的话直接激活,未创建的话创建并加入content-panel
        if (record.get('leaf')) {
            if(record.get('optype')=='window'){
                var win= Ext.getCmp(record.get('url'));
                if(!win){
                    win=Ext.widget(record.get('url'))
                }
                win.show();
            }
            else{
                var panel = Ext.getCmp(record.get('id'));
                if(!panel){ 
                    panel ={
                        id:record.get('url'),
                        title: record.get('text'),
                        xtype:record.get('url'),
                        closable: true 
                    };
                    this.openTab(panel,record.get('url'));
                }else{
                    var main = Ext.getCmp("content-panel");
                    main.setActiveTab(panel); 
                }
            }
           
        }  },
     openTab : function (panel,id){
        var o = (typeof panel == "string" ? panel : id || panel.id);
        var main = Ext.getCmp("content-panel");
        var tab = main.getComponent(o);      
        if (tab) {
            main.setActiveTab(tab); 
        } else if(typeof panel!="string"){ 
            panel.id = o; 
            var p = main.add(panel); 
            main.setActiveTab(p); 
        } 

    } 

});
//app.jsExt.Loader.setConfig({enabled: true});     
Ext.application({
    name:'et',          
    autoCreateViewport: true,
    appFolder:'app',    'Menu'        //加入菜单的controller
    ]
});  我们只要在后台将菜单按照固定格式的json将数据传过来即可,下面我们看一下一个简单菜单的json数据:


[{"text":"题目管理",
  "mid":"1",
  "cls":"folder",
  "leaf":false,
  "expanded": true,
  "children":[{"text":"题目列表",
                 "mid":"2",
                 "cls":"file",
                 "url":"subjectlist",
                 "leaf":true,
                 "children":[]}
               ]
 },{"text":"分组管理",
  "mid":"3",
  "cls":"folder",
  "leaf":false,
  "expanded": true,
  "children":[{"text":"选题分组确认",
                 "mid":"4",
                 "cls":"file",
                 "url":"mstudentlist",
                 "leaf":true,
                 "children":[]},
                 {"text":"分组列表",
                 "mid":"5",
                 "cls":"file",
                 "url":"mstudentlist",
                 "leaf":true,
                 "children":[]},
                 {"text":"报告审阅",
                 "mid":"6",
                 "cls":"file",
                 "url":"mstudentlist",
                 "leaf":true,
                 "children":[]}
               ]
 }]  其中我们可以看到,text指定了结点名,cls指定了图标样式(如folder为文件夹图标,file为文件图标),leaf指定是否为叶子结点,children内嵌套子结点。其他几个均为自定义,如这里url来指定打开panel的别名。

  基本的menu的用法就是这么简单,如果有更高的需求,如添加复选按钮、可拖动、动态编辑等,可参考extjs自带的实例代码。

  最后讨论一下json的生成,对于灵活性比较高的系统(如权限管理),一般把每个菜单项存在数据库比较方便,可根据情况组合后拼接json返回前台。但是很多时候我们或许并不需要这么高的灵活度,例如每个角色菜单固定,那么这是我们可以考虑按照如上json格式将每个菜单写进一个json文件,在用户登陆时判断角色加载对应文件即可。这样做能够省不少事(但要注意防止用户直接打开json文件路径,来越权操作功能,所以后台最好在拦截器里再进行下判断)。

 

点击复制链接 与好友分享!回本站首页
相关TAG标签 菜单
上一篇:jquery第一行代码有意思的两点
下一篇:JS实现商品倒计时
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站