资讯专栏INFORMATION COLUMN

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

X1nFLY / 3073人阅读

摘要:结构实践三完善基本页面一般经典的后台管理系统,都是左侧菜单右侧结构布局。不免俗,咱也这么实现定义左侧导航菜单新建采用的组件构建一个导航菜单为了显示图标,引入字体图标,在引入引入定义导航菜单数据功能菜单展开节点。

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());
                },
            }
        });
    }

});

现在,整个项目结构应该如图:

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92700.html

相关文章

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

    摘要:上篇实现了基本的代码架构,控制器动态加载功能以及一个基础的页面布局,本节开始,将陆续完善这个页面。页面底部区域,主要显示版权信息等,也可以显示个时间啥的。。。头部和底部定义完毕后,需要在中引入对应位置。 上篇实现了基本的代码架构,控制器动态加载功能以及一个基础的页面布局,本节开始,将陆续完善这个页面。 目标 如前所述,我们的页面包含这么几个区域: header: UI顶部区域,显示系...

    zhkai 评论0 收藏0
  • extjs-mvc结构实践(二):基本页面

    摘要:接着来,上一篇搭建了基本的项目骨架,到最后,其实啥也没看见。。。目标全屏显示左侧导航菜单,右侧标签页切换操作内容区域。一般模型与你后台返回的数据结构一一对应。给其他组件提供一致接口使用数据。整个构成一个所谓的。 接着来,上一篇搭建了基本的项目骨架,到最后,其实啥也没看见。。。书接上回,开始写UI效果。 目标 全屏显示、左侧导航菜单,右侧标签页切换操作内容区域。包含header和foo...

    changfeng1050 评论0 收藏0
  • extjs-mvc结构实践(一):搭建基础架构

    摘要:今天开始,一点点记录一下使用搭建一个基础结构的过程。没办法,记性差这种结构的前端,主要是面向后台信息管理系统,可以最大限度的规范前端代码结构和数据结构。 今天开始,一点点记录一下使用extjs6.2.0搭建一个基础MVC结构的过程。没办法,记性差:)这种结构的UI前端,主要是面向后台信息管理系统,可以最大限度的规范前端代码结构和数据结构。做网站 或者手机端,这种方式全引入了extjs,...

    kamushin233 评论0 收藏0
  • extjs-mvc结构实践(四):导航菜单与控制器模块联动

    摘要:根据模块创建模块失败。在中,我们配置了标明了这是一个控制器模块,点击后会去触发控制器加载动作。正常情况下同一个模块的只加载一次。 前面几篇文档,我们基本实现了一个静态的extjs页面,本篇开始,实现左侧导航树与右侧内容的联动,也就是点击导航菜单,加载对应模块页面和业务逻辑,实现js文件的按需加载。 业务需求是这样的: 左侧的treelist,当点击某个节点的时候,系统根据tree数据里...

    figofuture 评论0 收藏0
  • extjs-mvc结构实践(五):实现用户管理的增删改查

    摘要:而且上一篇文章中,也已经实现了一个基本的用户管理列表页面。接着上一篇,完善用户管理,实现增删改。为了用户体验,增加和修改用户信息的表单,都放在弹窗中进行。 经过前面几篇文章的介绍,一个基本的MVC结构应该是具备了。而且上一篇文章中,也已经实现了一个基本的用户管理列表页面。接着上一篇,完善用户管理,实现增删改。为了用户体验,增加和修改用户信息的表单,都放在弹窗中进行。避免跳转页面。 定义...

    wendux 评论0 收藏0

发表评论

0条评论

X1nFLY

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<