zoukankan      html  css  js  c++  java
  • ExtJs4实战流量统计系统----权限该怎么实现&自定义ToolBar(五)

    抱歉,最近比较忙,更新的比较慢~

    =========================分隔线====================================

    流量系统,是开放给内部所有用户使用,用于查询网站相关流量数据。

    Boss们需要能看到所有栏目的所有流量数据,而普通编辑们,则只能查看自己负责栏目的流量数据;

    管理员需要给所有人设置权限的权限;

    。。。。。。

    对于普通的Web应用程序或MVC来说,可以通过控制html元素的显示与否、可用与否来实现权限。

    而对于ExtJs来说,如何实现就是另一回事了。

    =========================分隔线====================================

    先来看看有哪些地方需要配置权限吧。

    左边手风琴有三个部分,Accordion控件不像Tree一样,可以从服务端加载数据生成控件,它只能手动的逐个添加子项。

    所以要实现权限控制,只好从服务端加载完权限信息后,再来控制各部分显示与否。

    另外,如果手风琴的子项内,也就是内部的Tree控件,没有任何节点的话,则自动将该子项隐藏。

    Ext.define('Yiqi.Main.SysSetTree', {
        extend: 'Ext.tree.Panel',
        requires: ['Yiqi.Common.Model.FunctionMenu'],
    
        parentId: 2,
        loadUrl: '',
        initComponent: function () {
            this.loadMask = new Ext.LoadMask(this, { msg: '加载中...' });
            this.buildStore();
            var me = this;
            Ext.apply(this, {
                rootVisible: false,
                lines: false,
                store: this.dataStore,
                listeners: {
                    itemclick: this.onItemClick,
                    beforeitemexpand: function () {
                        me.loadMask.show();
                    },
                    itemexpand: function () {
                        me.loadMask.hide();
                    },
                    load: function (store, obj, records, eOpts) {
                        if (!me.loadMask.isHidden()) {
                            me.loadMask.hide();
                        }
                        if (records.length <= 0) {
                            me.ownerCt.remove(me);//--如果没有子项,则隐藏
                        }
                    }
                }
            });
            this.callParent(arguments);
        }
    });

    各部分里边的内容,都是Tree控件,这个不用多说也能想到,直接在服务端返回可用的就行。

    权限配置功能也比较简单。

    =========================分隔线====================================

    左侧手风琴比较简单。

    而下边这个,就比较麻烦了。

    这是哪?这是流量数据显示界面顶部的工具条(Toolbar),用于切换数据显示。

    是的,并非所有栏目的功能都一样。

    比如:某些栏目才有地理信息统计,某些栏目才有访问排行。。。。。。

    如果在左侧加一个Tree控件来显示所有功能的话,那么就简单多了,对吧。

    但这样的话,就严重挤压了图表的空间,对于这样一个系统,图表及数据的展示,才是重点。

    而在顶部以一个工具条的方式显示菜单的话,似乎就简洁多了。。。

    好吧,那就这么干吧。。。

    =========================分隔线====================================

    一般Toolbar都是固定的,而基于服务端数据的Toolbar则是灵活的。

    对Toolbar子组件的类型,有三种要求:

      1、纯分组用,就像文件夹一样;

      2、带功能的分组,即有子组件的按钮,在ExtJs里,叫SplitButton。

      3、就是纯按钮了。

    先看一下用来加载Toolbar的数据是什么样的。

    功能地址:就是点击按钮后,会加载的功能地址,也是功能对应的js文件路径。这个在之前的文章里也说过。

    可以看到,有些项目的功能地址是空的,没错,就是用这个字段来区别类型。

    有子项目,功能地址为空,则说明是纯分组用的;有子项目,功能地址也不为空,则说明是带分组的功能按钮;没有子项目的就是纯按钮咯。

    =========================分隔线====================================

    从服务端加载好这些数据后,逐一循环,根据这个规则来决定ExtJs需要创建的类型,创建完成,再add到Toolbar里。

    当然,理论上支持无限级子菜单。

    Ext.define('Yiqi.Show.Catagory.FunctionToolBar', {
        extend: 'Ext.toolbar.Toolbar',
        alias: 'widget.functionbar',
        catagoryId: 1,
        loadStatics: function (path, scope) { },
        handlerScope: null,
    
        initComponent: function () {
            Ext.apply(this, {
                items: [
                    //--一加载就显示Loading,提高用户体验
                    { xtype: 'displayfield', value: '<img src="/Scripts/ext4.2/resources/themes/images/default/grid/loading.gif"/> 菜单加载中......' }
                ]
            });
            this.callParent(arguments);
        },
        afterRender: function () {
            //--渲染完成后,再从服务端加载数据,并创建Toolbar
            this.loadEnabledMenu();
            this.callParent(arguments);
        },
        loadEnabledMenu: function () {
            var me = this;
            Ext.Ajax.request({
                url: '/FunctionMenu/GetEnabledList',
                params: {
                    catagoryId: me.catagoryId
                },
                method: 'POST',
                success: function (response, opts) {
                    Yiqi.Common.Tools.IsLogin(response);
                    var result = Ext.decode(response.responseText);
                    var menu = me.buildMenu(result);
                    me.removeAll(true);
                    me.add(menu);
                },
                failure: function (response, opts) {
                    Ext.Msg.alert("提示", "保存失败(报错)~!");
                }
            });
        },
        buildMenu: function (list) {
            var me = this;
            var menu = [];
            //--循环所有
            Ext.Array.each(list, function (m) {
                menu.push(me.createSingle(m));
            });
            return menu;
        },
        createSingle: function (data) {
            var me = this;
            var menu = {};
            //--功能地址不为空
            if (!Ext.isEmpty(data.LoadPath, true) && Ext.String.trim(data.LoadPath).length > 0) {
                if (data.Children.length > 0) {
                    menu.xtype = 'splitbutton';
                }
                if (me.handlerScope) {
                    menu.scope = me.handlerScope;
                }
                menu.handler = function () {
                    this.createItem(data.LoadPath, menu);
                    //me.loadStatics(data.LoadPath, menu); 
                }
            }
    
            menu.text = data.text;
            menu.iconCls = data.iconCls;
            //--有子菜单,则继续循环
            if (data.Children.length > 0) {
                var childMenu = me.buildMenu(data.Children);
                menu.menu = {
                    items: childMenu
                };
            }
            return menu;
        }
    });
  • 相关阅读:
    docker与虚拟机性能比较
    CAP原则(CAP定理)、BASE理论
    CAP 定理的含义
    JVM监测分析JConsole
    JConsole详解
    jconsole工具使用
    轻松看懂Java字节码
    JVM 虚拟机字节码指令表
    深入理解java虚拟机(六)字节码指令简介
    大话+图说:Java字节码指令——只为让你懂
  • 原文地址:https://www.cnblogs.com/uphenson/p/3620931.html
Copyright © 2011-2022 走看看