Extjs 权限树的实现(上)

前言

由于篇幅过长,将分为上下两章

extjs5

 

正题

从头开始搭建一个角色管理的模块,主要功能是根据权限列表来分配权限

一、Model

编写一个model,这个model和java的bean类似,主要是定义字段,根据需求,我们的model里有如下字段,主要代码如下:

// 角色管理-model           
Ext.define('pay.model.RoleManager', {            // pay.model.RoleManager决定了从什么路径去找这个store  
    extend: 'Ext.data.Model',                    //继承自Ext.data.Model
    fields: [                                    //字段定义
        {name:'id',type: 'string'},              //主键id
        {name:'role_name',type:'string'},        //角色名称
        {name:'role_info',type:'string'},        //角色介绍
        {name:'auth_list',type:'string'},        //权限集合
        {name:'create_user',type:'string'},      //创建该角色的用户
        {name:'create_date',type:'string'},      //创建时间
        {name:'last_modify_user',type:'string'}, //最后一次修改该角色的用户
        {name:'last_modify_date',type:'string'}  //最后一次修改该角色的时间
    ],
    idProperty : 'id'           //主键属性
});

 

二、Store

store主要负责通过ajax接收来自后台的数据,然后渲染到界面上,代码如下,注释很清晰

// 角色管理-store
Ext.define('pay.store.RoleManager', {
    extend: 'Ext.data.Store',
    alias: 'store.roleManager',             //设置store别名
    model: 'pay.model.RoleManager',         //绑定相应的model
    storeId:'roleManager',                  //store的唯一ID,可通过Ext.storeMgr.get('roleManager')来获取并操作
    pageSize:30,                            //每页条数,分页使用的,因为我们这里数据渲染到grid里
    autoLoad: true,                         //自动加载
    proxy: {
        type: 'ajax',
        url: ipPort+'/role'+backend,        //ajax的url
        withCredentials : true,
        async:false,                        //不异步加载,我这里开启的话会导致添加等操作后grid数据不会及时更新
        actionMethods:{
            create: "POST", read: "POST", update: "POST", destroy: "POST"       //都用POST请求
        },
        //后台要求的字段(pagesize  limit start这三个是默认有的)
        extraParams:{json:Ext.encode({
            "opr": "select",
            "cond":{}
        })},
        reader: {
            type: 'json',
            totalProperty:'total',     //json中标识着总数的字段
            rootProperty: 'result',    //json中标识着root的字段
            successProperty: 'success' //json中标识着状态的字段
        }
    }
});

 

三、View

View是主视图,来定义grid数据,代码如下:

// 角色管理-view
Ext.define('pay.view.roleManager.RoleManager', {
    extend: 'Ext.grid.Panel',
    xtype: 'roleManager',
    itemId:'roleManager',	//itemId作为每个板块的唯一标识,与xtype相同
    requires: ['pay.store.RoleManager','Ext.selection.CheckboxModel'],//引入store
    controller:'roleManager',
    loadMask: true,
    columnLines: true,
    viewConfig:{
        enableTextSelection:true    //表格里的内容可复制
    },
    selModel: {
        injectCheckbox: 0,
        mode: "SIMPLE",     //"SINGLE"/"SIMPLE"/"MULTI"
        checkOnly: true     //只能通过checkbox选择
    },
    selType: "checkboxmodel",
    layout:'fit',
    stripeRows: true,
    closable:true,
    initComponent:function(){
        var me = this;
        var store = Ext.create('pay.store.RoleManager');//创建store实例
        this.store = store;
        me.columns = [{
            text: 'ID',
            width:80,
            dataIndex: 'id',
            align:'center'
        },{
            text: '角色名称',
            flex: 1,
            dataIndex: 'role_name',
            align:'center'
        }, {
            text: '角色介绍',
            flex: 1,
            dataIndex: 'role_info' +
            '',
            align:'center'
        }, {
            text: '权限集合',
            flex: 1,
            dataIndex: 'auth_list',
            align:'center'
        }, {
            text: '创建者',
            flex: 1,
            dataIndex: 'create_user',
            align:'center'
        }, {
            text: '创建时间',
            flex: 1,
            dataIndex: 'create_date',
            align:'center'
        }, {
            text: '最近修改者',
            flex: 1,
            dataIndex: 'last_modify_user',
            align:'center'
        }, {
            text: '最近修改时间',
            flex: 1,
            dataIndex: 'last_modify_date',
            align:'center'
        }
        ];
        me.dockedItems = [{
            xtype: 'roleManagerQuery',   // 查询面板
            dock: 'top'
        },
            {
                xtype: 'roleManagerOprbar', 	 // 按钮toolbar
                dock: 'top'
            },
            {
                xtype: 'pagingtoolbar',	         //分页
                dock: 'bottom',
                store:store,
                displayInfo: true
            }];
        me.callParent();
    }
});

这时候如果后台接口已写完就可以看到效果了,这期主要是取得后台返回过来的数据,上一张效果图

qq%e6%88%aa%e5%9b%be20160930151554

我们在主视图View里定义了查询的表单以及操作栏,这里我们创建下对应的js,代码很容易理解,不解释了

// 角色管理-oprbar
Ext.define('pay.view.roleManager.region.RoleManagerOprbar', {
    extend: 'Ext.toolbar.Toolbar',
    xtype: 'roleManagerOprbar',
    initComponent: function () {
        this.items = [
            {
                text: '添加',
                glyph: 0xf067,
                tooltip:'新增一条记录',
                handler:'onAdd'
            }, {
                text: '编辑',
                glyph: 0xf044,
                tooltip:'编辑记录',
                handler:'onEdit'
            },
            {
                text: '删除',
                glyph: 0xf014,
                tooltip:'删除记录',
                handler:'onDelete'
            }
        ];
        this.callParent();
    }
});

 

// 角色管理-query
Ext.define('pay.view.roleManager.region.RoleManagerQuery', {
    extend: 'Ext.panel.Panel',
    alias:  'widget.roleManagerQuery',
    items:{
        xtype:'form',
        reference: 'form',
        bodyPadding: 10,
        border: false,
        layout:{
            type:'vbox',
            align: 'stretch'
        },
        //查询区域
        items:[
            {
                xtype:'fieldset',
                title:'查询区(点击展开)',
                collapsed:true,     //默认关闭
                collapsible: true,  //是否可关闭
                padding:'10 10 15 10',
                items : [
                    {
                        defaults:{
                            xtype:'textfield',
                            margin:'0 20 10 0',
                            labelWidth:70,
                            width:250
                        },
                        layout : 'column',
                        frame : true,
                        margin:'0 0 10 0',
                        baseCls : 'my-panel-no-border',  //去掉边框
                        items :[
                            {
                                fieldLabel: 'ID',
                                name:'id' ,
                                labelWidth:30,
                                width:120
                            },
                            {
                                fieldLabel: '角色名称',
                                name:'role_name'
                            },
                            {
                                fieldLabel:'创建者',
                                name:'create_user'
                            },
                            {
                                fieldLabel:'最近修改者',
                                name:'last_modify_user'
                            }
                        ]
                    },
                    {
                        layout : 'column',
                        frame : true,
                        baseCls : 'my-panel-no-border',  //去掉边框
                        items : [
                            {
                                xtype:'button',
                                width:64,
                                text:'查询',
                                margin:'0 10 0 0',
                                handler:'onSearch'
                            },
                            {
                                xtype:'button',
                                id:'btn-roleManager-reset',
                                text:'重置',
                                margin:'0 0 0 10',
                                handler:'onSearch'
                            }
                        ]
                    }
                ]
            }
        ]
    }
});

以及对应的增加编辑的form,在这里,我们给添加和编辑使用同一个form,首先根据要求创建form,这里主要是利用Ext的布局,相信有基础就能看懂,否则接下来的也不用看

// 角色管理-form
Ext.define('pay.view.roleManager.region.RoleManagerForm', {
    extend: 'Ext.window.Window',
    xtype: 'roleManagerForm',
    layout: 'fit',
    modal: true,
    title: '角色管理',
    id: 'roleManagerForm',
    controller: 'roleManager',
    border:true,
    items:{
        xtype:'form',
        width:360,
        bodyPadding: 10,
        border: false,
        layout:{
            type:'vbox',
            align: 'stretch'
        },
        defaults:{
            xtype:'textfield',
            allowBlank:false,
            blankText:'此输入框为必填项',
            msgTarget:'side',
            width:320
        },
        items:[
            {
                fieldLabel:'ID',
                name:'id',
                readOnly : true,        //编辑时只读
                disabled:true,          //添加时此值不会传给后台
                hidden:true             //在form中隐藏
            },
            {
                fieldLabel:'角色名称',
                name:'role_name'
            },
            {
                fieldLabel:'角色介绍',
                name:'role_info'
            },
            {
                fieldLabel:'权限列表',
                name:'auth_list'
            },
            {
                xtype:'treepanel',
                id:'auth-list-tree',
                // checkModel: 'cascade',   //对树的级联多选
                // onlyLeafCheckable: true,//对树所有结点都可选
                height:300,
                animate: false,
                rootVisible: false,
                autoScroll:true,
                useArrows:true,
                root: {
                    expand:true
                    // nodeType: 'async'
                },
                store:new Ext.data.TreeStore({
                    // autoLoad: true,
                    proxy: {
                        type: "ajax",
                        actionMethods: { read: "POST" },
                        url: 'app/data/tree.json',
                        reader: {
                            type: "json",
                            rootProperty:'children'
                        }
                    }
                }),
                listeners: {
                    "checkchange": function(node,checked) {
                        checkChildNode(node, checked);
                        if(!node.hasChildNodes()){
                            //如果有一个取消选中,父节点也取消选中
                            if(!checked){
                                node.parentNode.set('checked',false);
                            }
                            //如果所有子节点都选中,父节点才选中
                            else{
                                var child = node.parentNode.childNodes;
                                var flag = true;
                                for(var i=0;i<child.length;i++){
                                    if(child[i].data.checked == false){
                                        flag = false;
                                    }
                                }
                                if(flag == true){
                                    node.parentNode.set('checked',true);
                                }
                            }
                        }
                    },
                    afterrender:function (tree) {
                        console.log("render success");
                    }
                }
            }
        ],
        buttons:[
            {
                id:'btn-roleManager-add',
                text:'确定',      //添加提交的按钮
                formBind: true,  //表单合法才会可点击
                handler:'onSubmit'
            },
            {
                id:'btn-roleManager-edit',
                text:'确定',      //编辑提交的按钮
                formBind: true,  //表单合法才会可点击
                handler:'onSubmit'
            },
            {
                text:'关闭',
                handler:'onCancelClick'
            },
            {
                text:'测试',
                id:'btn-roleManager-setTreeValue',
                hidden:true,
                listeners:{
                    click:function(){
                        var tree = Ext.getCmp('auth-list-tree');
                        var form = this.up('form').getForm();
                        var originArr = form.findField('auth_list').getValue().split(',');
                        var arr = new Array();      //声明数组来存放权限id
                        tree.expandAll();
                        var firstNodes = tree.getRootNode().childNodes;     //客户信息/合同协议号之类
                        for(var k=0;k<originArr.length;k++){
                            for(var i=0;i<firstNodes.length;i++){
                                var secondNodes = firstNodes[i].childNodes;
                                for(var j=0;j<secondNodes.length;j++){
                                    // 如果查找到的id和auth_list相同
                                    if(secondNodes[j].data.id == originArr[k]){
                                        secondNodes[j].set('checked',true);
                                    }
                                    //将所有打了勾的push到新数组并传递给ajax
                                    if(secondNodes[j].data.checked == true){
                                        arr.push(secondNodes[j].id);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        ]
    }
});

 

这一期就到此结束,下一期主要讲增删查改的逻辑实现,主要是Controller方面,地址是
http://vinceok.com/javascript/274.html

共有 1 条评论

Top