extjs-mvc结构实践(三):完善基本页面2

extjs-mvc结构实践(三):完善基本页面2

一般经典的后台管理系统,都是左侧菜单右侧tabs结构布局。不免俗,咱也这么实现!

定义左侧导航菜单

新建:app/luter/view/main/Navlist.js



/**
 * 采用extjs6的list tree组件构建一个导航菜单
 */
Ext.define('luter.view.main.Navlist', {
    extend: 'Ext.list.Tree',
    alias: 'widget.navlist',
    width: 240,
    minWidth: 120,
    frame: true,
    border: true,
    split: true,
    expanderFirst: false,
    expanderOnly: false,
    highlightPath: true,
    itemId: 'navigationTreeList',
    ui: 'navigation',
    store: 'NavTreeStore',
    initComponent: function () {
        this.callParent(arguments);
    }
});


为了显示icon图标,引入font awsome字体图标,在app.html引入:


  
    

定义导航菜单数据Store:app/luter/store/NavTreeStore.js

Ext.define('luter.store.NavTreeStore', {
    extend: 'Ext.data.TreeStore',
    fields: ['id', 'text', 'leaf', 'module', 'tips', 'icon'],
    autoLoad: true,
    proxy: {
        type: 'ajax',
        url: 'app/testdata/menu.json',
        reader: {
            type: 'json',
            root: 'children',
            successProperty: 'success'
        },

        actionMethods: {
            read: 'GET'
        },
        listeners: {
            exception: function (proxy, response, operation, eOpts) {
                DealAjaxResponse(response);
            }
        }
    },
    root: {
        text: '功能菜单',
        id: 0,
        leaf: false,
        expanded: false
    },

    listeners: {
        beforeload: function (store, operation, eOpts) {
            if (store.isLoading()) return false;
        },

        nodeappend: function (me, node, index, eOpts) {
            //展开节点。
            if (!node.isRoot() && !node.get('leaf')) {
                node.set('expanded', true);
            }

        }
    }
});
/**
 * 解决问题:主要是因为RootTreeItem引起
 * ext-all.js?v=20000000:22 Uncaught TypeError: b.getFloated is not a function
 */

Ext.define('Overrides.list.RootTreeItem', {
    override: 'Ext.list.RootTreeItem',
    config: {
        floated: null
    },
    setFloated: function (floated) {
        var me = this,
            el = me.element,
            placeholder = me.placeholder,
            node, wasExpanded;
        if (me.treeItemFloated !== floated) {
            if (floated) {
                placeholder = el.clone(false, true);
                placeholder.id += '-placeholder';
                me.placeholder = Ext.get(placeholder);
                me.wasExpanded = me.getExpanded();
                me.setExpanded(true);
                el.addCls(me.floatedCls);
                el.dom.parentNode.insertBefore(placeholder, el.dom);
                me.floater = me.createFloater();
            }
            else if (placeholder) {
                wasExpanded = me.wasExpanded;
                node = me.getNode();
                me.setExpanded(wasExpanded);
                if (!wasExpanded && node.isExpanded()) {
                    me.preventAnimation = true;
                    node.collapse();
                    me.preventAnimation = false;
                }
                me.floater.remove(me, false);
                el.removeCls(me.floatedCls);
                placeholder.dom.parentNode.insertBefore(el.dom, placeholder.dom);
                placeholder.destroy();
                me.floater.destroy();
                me.placeholder = me.floater = null;
            }
            me.treeItemFloated = floated;
        }
    },
    getFloated: function () {
        return this.treeItemFloated;
    },
    runAnimation: function (animation) {
        return this.itemContainer.addAnimation(animation);
    },
    stopAnimation: function (animation) {
        animation.jumpToEnd();
    },
    privates: {
        createFloater: function () {
            var me = this,
                owner = me.getOwner(),
                ownerTree = me.up('treelist'),
                floater,
                toolElement = me.getToolElement();
            me.floater = floater = new Ext.container.Container({
                cls: ownerTree.self.prototype.element.cls + ' ' + ownerTree.uiPrefix + ownerTree.getUi() + ' ' + Ext.baseCSSPrefix + 'treelist-floater',
                floating: true,
                width: Ext.isIE8 ? 200 : (ownerTree.expandedWidth - toolElement.getWidth()),
                shadow: false,
                renderTo: Ext.getBody(),
                listeners: {
                    element: 'el',
                    click: function (e) {
                        return owner.onClick(e);
                    }
                }
            });
            floater.add(me);
            floater.show();
            floater.el.alignTo(toolElement, 'tr?');
            return floater;
        }
    }
});

写点模拟菜单数据:app/testdata/menu.json



[
  {
    "id": "111",
    "text": "系统管理",
    "href": null,
    "leaf": false,
    "iconCls": "fa fa-home",
    "module_id": "no sign",
    "qtip": "这个地方显示鼠标悬停提示",
    "children": [
      {
        "id": "11111",
        "text": "用户管理",
        "href": null,
        "leaf": true,
        "iconCls": "fa fa-user",
        "module_id": "sys.UserModule",
        "qtip": "系统用户管理",
        "children": []
      },
    ]
  },
  {
    "id": "111",
    "text": "系统管理",
    "href": null,
    "leaf": false,
    "iconCls": "fa fa-home",
    "module_id": "no sign",
    "qtip": "这个地方显示鼠标悬停提示",
    "children": [
      {
        "id": "11111",
        "text": "用户管理",
        "href": null,
        "leaf": true,
        "iconCls": "fa fa-user",
        "module_id": "sys.UserModule",
        "qtip": "系统用户管理",
        "children": []
      },
    ]
  }
  
]

定义中间视图展示部分tabpanel:app/luter/view/main/ContentPanel.js


/*
 *系统主页面TabPanel面板
 */
 Ext.define('luter.view.main.ContentPanel', {
    extend: 'Ext.tab.Panel',
    alias: 'widget.syscontentpanel',
    border: false,
    plugins: [Ext.create('luter.ux.TabCloseMenu', {//用到了一个tab右键关闭插件
        closeTabText: '关闭当前页',
        closeOthersTabsText: '关闭其他页',
        closeAllTabsText: '关闭所有页',
        closeIcon: +' fa fa-remove red-color',
        closeOtherIcon: ' fa fa-remove red-color',
        closeAllIcon: 'fa fa-remove red-color',
    })],
    items: [{
        xtype: 'panel',
        id: 'dashboardpanel',
        title: 'DASHBOARD',
        baseCls: 'home-body',
        closeable: false,
        glyph: 42
    }]

});

在viewport中引入导航树和内容区域,编辑:app/luter/view/main/Viewport.js,内容如下:

/**
 * 主视图占满全屏是个viewport
 */
Ext.define('luter.view.main.ViewPort', {
    extend: 'Ext.Viewport',
    alias: 'widget.viewport',//别名,与xtype对应
    layout: 'border',//东南西北中布局,边界嘛
    stores: [],
    //动态加载相关组件定义的js,相当于java的:import com.xxx.*;
    requires: ['luter.view.main.Header', 'luter.view.main.Footer', 'luter.view.main.Navlist', 'luter.view.main.ContentPanel'],
    initComponent: function () {
        var me = this;
        Ext.apply(me, {
            items: [{
                region: 'north',
                xtype: 'appheader'
            }, {
                region: 'west',
                xtype: 'navlist'//引入导航菜单
            }, {
                region: 'center',
                xtype: 'syscontentpanel'//引入内容tabpanel

            }, {
                region: 'south',
                xtype: 'sysfooter'
            }]
        });
        me.callParent(arguments);
    }
});

最后,别忘记在主控制器里加入导航菜单的Store,

修改主控制器:app/luter/controller/MainController.js


Ext.define('luter.controller.MainController', {
    extend: 'Ext.app.Controller',
    views: ['main.ViewPort'],
    stores: ['NavTreeStore'],//引入导航树的Store
    init: function (application) {
        var me = this;
        this.control({
            'viewport': {//监听viewport的初始化事件,可以做点其他事情在这里,如有必要,记得viewport定义里的alias么?
                'beforerender': function () {
                    console.log('viewport begin render at:' + new Date());
                },
                'afterrender': function () {
                    console.log('viewport  render finished at:' + new Date());
                },
            }
        });
    }

});

现在,整个项目结构应该如图:
extjs-mvc结构实践(三):完善基本页面2_第1张图片

打开app.html,界面应该如图:

extjs-mvc结构实践(三):完善基本页面2_第2张图片

下一篇,实现左侧菜单点击与内容区域tabpanel联动功能,并且实现控制器的动态加载。

你可能感兴趣的:(javascript,extjs)