Browse Source

导航菜单openTab逻辑优化,不再使用dataset读取节点数据

zhuth 6 years ago
parent
commit
f978ec0fac

+ 7 - 0
frontend/saas-web/app/model/main/NavMenu.js

@@ -0,0 +1,7 @@
+Ext.define('saas.model.main.NavMenu', {
+    extend: 'saas.model.Base',
+    fields: [
+        { name: 'text', type: 'string' },
+        { name: 'iconCls', type: 'string' }
+    ],
+});

+ 14 - 0
frontend/saas-web/app/view/main/MainModel.js

@@ -9,5 +9,19 @@ Ext.define('saas.view.main.MainModel', {
     data: {
         navWidth: 160,
         smallNavWidth: 64,
+    },
+
+    stores: {
+        navMenu: {
+            model: 'saas.model.main.NavMenu',
+            autoLoad: true,
+            proxy: {
+                type: 'ajax',
+                url: 'resources/json/navigation.json',
+                reader: {
+                    type: 'json'
+                }
+            }
+        }
     }
 });

+ 121 - 152
frontend/saas-web/app/view/main/Navigation.js

@@ -1,8 +1,6 @@
 Ext.define('saas.view.main.Navigation', {
-    extend: 'Ext.panel.Panel',
+    extend: 'Ext.view.View',
     xtype: 'main-navigation',
-    ui: 'nav',
-
     reference: 'navigationTreeList',
 
     width: 180,
@@ -12,37 +10,38 @@ Ext.define('saas.view.main.Navigation', {
 
     menuPadding: 0,
 
+    bind: {
+        store: '{navMenu}'
+    },
+
+    renderTpl: [
+        '<div id="{id}-innerCt" data-ref="innerCt" role="presentation">',
+        '{%this.renderContent(out,values)%}',
+        '</div>'
+    ],
+    tpl: ['<ul class="x-navlist">',
+        '<tpl for=".">',
+        '<li class="x-navitem">',
+        '<div class="x-navitem-body">',
+        '<div class="nav-inner-wrap" style="margin-left: 0px;">',
+        '<div class="nav-inner-icon {iconCls}"></div>',
+        '<div class="nav-inner-text">{text}</div>',
+        '</div>',
+        '</div>',
+        '</li>',
+        '</tpl>',
+        '</ul>'
+    ],
+
+    overItemCls: 'x-navitem-over',
+    selectedItemCls: 'x-navitem-selected',
+    singleSelect: true,
+    itemSelector: '.x-navitem',
+
     initComponent: function () {
         var me = this;
-        var view = new Ext.DataView({
-            store: Ext.create('Ext.data.Store', {
-                autoLoad: true,
-                fields: ['text', 'iconCls'],
-                proxy: {
-                    type: 'ajax',
-                    url: 'resources/json/navigation.json',
-                    reader: {
-                        type: 'json'
-                    }
-                }
-            }),
-            tpl: new Ext.XTemplate('<ul class="x-navlist">',
-                '<tpl for=".">',
-                    '<li class="x-navitem">',
-                        '<div class="x-navitem-body">',
-                            '<div class="nav-inner-wrap" style="margin-left: 0px;">',
-                                '<div class="nav-inner-icon {iconCls}"></div>',
-                                '<div class="nav-inner-text">{text}</div>',
-                            '</div>',
-                        '</div>',
-                    '</li>',
-                '</tpl>',
-            '</ul>'),
-            trackOver: true,
-            overItemCls: 'x-navitem-over',
-            selectedItemCls: 'x-navitem-selected',
-            singleSelect: true,
-            itemSelector: '.x-navitem',
+
+        Ext.apply(me, {
             listeners: {
                 itemmouseenter: function(navView, record, navItem, index, e, eOpts) {
                     window.clearTimeout(me.Timer);
@@ -63,98 +62,108 @@ Ext.define('saas.view.main.Navigation', {
                 scope: me
             }
         });
-
-        Ext.apply(me, {
-            items: [view]
-        });
-
-        me.view = view;
-        me.callParent();
+        me.callParent(arguments);
     },
 
-    // clickNavMenu: function (view, record, item, index, e, eOpts) {
-    //     var me = this;
-    //     this.showNavMenu(view, record, item, index, e, eOpts);
-    // },
-
     showNavMenu: function (navView, record, navItem, index, e, eOpts) {
         var me = this,
             recData = record.data,
             d = recData.items || [],
-            menuItems = JSON.parse( JSON.stringify( d ) ),
+            menuItems = JSON.parse(JSON.stringify(d)),
             itemBox = navItem.getBoundingClientRect(),
             pos = [itemBox.left + itemBox.width, itemBox.top],
-            id = recData.id,
-            menuId = 'navMenu-' + id,
+            menuId = 'navMenu-' + record.get('id'),
             menu = Ext.getCmp(menuId);
 
         //获取b2b权限
         var enableB2B = me.ownerCt.ownerCt.getViewModel().get('enableB2B');
 
-        if(enableB2B==null||enableB2B==0||enableB2B=='0'){
-            Ext.each(menuItems,function(item,index){
-                if(item.items.length>0){
-                    var l = item.items.length;
-                    for(var i = 0;i<l;i++){
-                        if(item.items[i].hasOwnProperty('b2b') && item.items[i].b2b == true){
+        Ext.each(menuItems,function(item,index){
+            if(item.items.length>0){
+                var l = item.items.length;
+                for(var i = 0;i<l;i++){
+                    if(item.items[i].hasOwnProperty('b2b')){
+                        if(((!enableB2B || enableB2B == '0') && item.items[i].b2b == true) || (!!enableB2B && item.items[i].b2b == false)) {
                             item.items.splice(i--,1);
                             l--;
                         }
-                    };
-                }
-            })
-        }else {
-            Ext.each(menuItems,function(item,index){
-                if(item.items.length>0){
-                    var l = item.items.length;
-                    for(var i = 0;i<l;i++){
-                        if(item.items[i].hasOwnProperty('b2b') && item.items[i].b2b == false){
-                            item.items.splice(i--,1);
-                            l--;
-                        }
-                    };
-                }
-            })
-        }
-            
+                    }
+                };
+            }
+        })
+
         if (!menu) {
-            var view = new Ext.DataView({
+            view = new Ext.DataView({
                 store: Ext.create('Ext.data.Store', {
                     fields: ['id', 'text', 'addType', 'viewType'],
                     data: menuItems
                 }),
                 tpl: new Ext.XTemplate('<div class="x-navitem-menu">',
                     '<div class="nav-menu-body">',
-                    '<tpl for=".">',
-                    '<div class="menu">',
-                        '<div class="menu-title">',
-                            '<span class="menu-title-text">{text}</span>',
-                        '</div>',
-                        '<div class="menu-content">',
-                            '<tpl for="items">',
-                            '<div class="menuitem">',
-                                '<div class="item-text" data-config="{config}" data-id="{id}" data-text="{text}" data-type="query" data-viewType="{viewType}">',
-                                    '{text}',
+                        '<tpl for=".">',
+                            '<div class="menu">',
+                                '<div class="menu-title">',
+                                    '<span class="menu-title-text">{text}</span>',
+                                '</div>',
+                                '<div class="menu-content">',
+                                    '<tpl for="items">',
+                                        '<div class="menuitem">',
+                                            '<div data-boundView="{id}" data-recordId="{id}" class="item-text" data-config="{config}" data-id="{id}" data-text="{text}" data-type="query" data-viewType="{viewType}">',
+                                                '{text}',
+                                            '</div>',
+                                            '<tpl if="this.hasAddType(addType)">',
+                                                '<div class="item-icon" data-id="{id}" data-text="{text}" data-type="form" data-viewType="{addType}">新增</div>',
+                                            '</tpl>',
+                                        '</div>',
+                                    '</tpl>',
                                 '</div>',
-                                '<tpl if="{addType}">',
-                                '<div class="item-icon" data-id="{id}" data-text="{text}" data-type="form" data-viewType="{addType}">新增</div>',
-                                '</tpl>',
                             '</div>',
-                            '</tpl>',
-                        '</div>',
-                    '</div>',
-                    '</tpl>',
+                        '</tpl>',
                     '</div>',
-                    '</div>'),
+                '</div>', {
+                    disableFormats: true,
+                    hasAddType: function(addType) {
+                        return !!addType;
+                    }
+                }),
                 trackOver: true,
                 overItemCls: 'menuitem-over',
                 selectedItemCls: 'menuitem-selected',
                 singleSelect: true,
-                itemSelector: 'menu',
-                listeners: {
-                    // boxready: function (view, width, height, eOpts) {
-                    // },
-                }
+                itemSelector: '.menu',
+                /** override */
+                updateIndexes: function(startIndex, endIndex) {
+                    var self = this,
+                        menu = self.up('menu'),
+                        nodes = self.all.elements,
+                        records = self.getViewRange(),
+                        selModel = self.getSelectionModel(),
+                        myId = self.id,
+                        i, j;
+
+                    startIndex = startIndex || 0;
+                    endIndex = endIndex || ((endIndex === 0) ? 0 : (nodes.length - 1));
+                    for (i = startIndex; i <= endIndex; i++) {
+                        let node = nodes[i];
+                        let record = records[i];
+
+                        
+                        let cnodes = node.children[1].children;
+
+                        for(j = 0; j < cnodes.length; j++) {
+                            let cnode = cnodes[j];
+                            let crecord = record.data.items[j];
+                            !!Ext.get(cnode.children[0]) && Ext.get(cnode.children[0]).on('click', function() {
+                                me.openTab('', crecord);
+                                menu.hide();
+                            });
+                            !!Ext.get(cnode.children[1]) && Ext.get(cnode.children[1]).on('click', function() {
+                                me.openTab('add', crecord);
+                                menu.hide();
+                            });
+                        }
+                    }
+                },
             });
             var menu = Ext.create('Ext.menu.Menu', {
                 navView: navView,
@@ -171,17 +180,28 @@ Ext.define('saas.view.main.Navigation', {
         menu.items.items[0].store.removeAll();
         menu.items.items[0].store.loadData(menuItems);
         menu.showAt(pos);
-        me.refresh(menu.items.items[0],pos)
+        me.refreshMenu(menu.items.items[0], pos)
+    },
+
+    openTab: function(type, data) {
+        var viewType = data.viewType,
+            text = data.text,
+            config = data.config,
+            id = data.id,
+            addType = data.addType;
+
+        saas.util.BaseUtil.openTab(type == 'add' ? addType : viewType, text, 'maintab-' + type + '-' + id, config);
+
     },
 
-    refresh:function(view,pos){
+    refreshMenu: function (view, pos) {
         var me = this;
         var menu = view.up('menu'),
-        menuView = view.el.dom.getElementsByClassName('x-navitem-menu')[0],
-        menuBox = menuView.getBoundingClientRect(),
-        menuViewWidth = menuBox.width + me.menuPadding * 2,
-        menuViewHeight = menuBox.height + me.menuPadding * 2,
-        menuItem = menuView.getElementsByClassName('menuitem');
+            menuView = view.el.dom.getElementsByClassName('x-navitem-menu')[0],
+            menuBox = menuView.getBoundingClientRect(),
+            menuViewWidth = menuBox.width + me.menuPadding * 2,
+            menuViewHeight = menuBox.height + me.menuPadding * 2,
+            menuItem = menuView.getElementsByClassName('menuitem');
 
         menu.setX(pos[0]);
         menu.setWidth(menuViewWidth);
@@ -196,57 +216,6 @@ Ext.define('saas.view.main.Navigation', {
         view.el.dom.addEventListener('mouseleave', function (e) {
             menu.navItem.classList.remove(menu.navView.overItemCls);
             menu.hide();
-            // var ex = e.clientX,
-            //     ey = e.clientY,
-            //     box = menuView.getBoundingClientRect(),
-            //     navItem = menu.navItem,
-            //     navBox = navItem.getBoundingClientRect();
-
-            // if ((ex <= box.left && (ey <= (navBox.top - 5) || ey >= (navBox.top + navBox.height))) || ey <= (box.top - 5) || ex >= (box.left + box.width + 5) || ey >= (box.top + box.height + 5)) {
-            //     menu.navItem.classList.remove(menu.navView.overItemCls);
-            //     menu.hide();
-            // }
-        });
-
-        Ext.Array.each(menuItem, function (mi) {
-            var menuItemText = mi.getElementsByClassName('item-text');
-            var menuItemIcon = mi.getElementsByClassName('item-icon');
-
-            Ext.Array.each(menuItemText, function (item) {
-                item.addEventListener('click', function (e) {
-                    var target = e.target,
-                    dataset = target.dataset,
-                    viewType = dataset.viewtype,
-                    type = dataset.type,
-                    text = dataset.text,
-                    config = dataset.config,
-                    id = dataset.id;
-
-                    var tabTitle = text,
-                    tabId = 'maintab-' + type + '-' + id;
-
-                    menu.navItem.classList.remove(menu.navView.overItemCls);
-                    saas.util.BaseUtil.openTab(viewType, tabTitle, tabId,config);
-                    menu.hide();
-                });
-            });
-            Ext.Array.each(menuItemIcon, function (item) {
-                item.addEventListener('click', function (e) {
-                    var target = e.target,
-                    dataset = target.dataset,
-                    viewType = dataset.viewtype,
-                    type = dataset.type,
-                    text = dataset.text,
-                    id = dataset.id;
-
-                    var tabTitle ='新增' + text,
-                    tabId = viewType + '-add';
-
-                    menu.navItem.classList.remove(menu.navView.overItemCls);
-                    saas.util.BaseUtil.openTab(viewType, tabTitle, tabId);
-                    menu.hide();
-                });
-            });
         });
     },
 

+ 78 - 75
frontend/saas-web/app/view/main/Navigation.scss

@@ -6,6 +6,83 @@ $menu-body-background-color: #65678C;
 
 .x-navpanel {
     overflow: visible;
+    background-color: $nav-body-background-color;
+
+    .x-navlist {
+        position: relative;
+        list-style: none;
+        padding: 0;
+        margin: 0;
+        width: 100%;
+
+        .x-navitem {
+            cursor: default;
+            position: relative;
+            list-style: none;
+            padding: 0;
+            margin: 0;
+            outline: none !important;
+            
+            .x-navitem-body {
+
+                .nav-inner-wrap {
+                    position: relative;
+                    overflow: hidden;
+                    list-style: none;
+                    max-height: 60px;
+                    padding: 0 10px;
+                    display: flex;
+
+                    .nav-inner-icon {
+                        color: $nav-font-color;
+                        font-size: 24px;
+                        text-align: center;
+                        margin-left: 22px;
+                        display: inline;
+                        margin-right: 16px;
+
+                        &:before {
+                            line-height: 60px;
+                        }
+                    }
+
+                    .nav-inner-text {
+                        font-size: $nav-font-size;
+                        color: $nav-font-color;
+                        letter-spacing: 4px;
+                        text-align: left;
+                        line-height: 60px;
+                        height: 60px;
+                    }
+                }
+            }
+        }
+        .x-navitem-over {
+            .x-navitem-body {
+                background: #65678C;
+
+                .nav-inner-wrap {
+
+                    &:before {
+                        content: ' ';
+                        position: absolute;
+                        width: 8px;
+                        height: 60px;
+                        background: #34baf6;
+                        left: 0;
+                    }
+
+                    .nav-inner-icon {
+                        color: $nav-font-color-over;
+                    }
+
+                    .nav-inner-text {
+                        color: $nav-font-color-over;
+                    }
+                }
+            }
+        }
+    }
 
     .x-panel-bodyWrap {
         overflow: visible;
@@ -24,81 +101,6 @@ $menu-body-background-color: #65678C;
     
                 .x-autocontainer-innerCt {
     
-                    .x-navlist {
-                        position: relative;
-                        list-style: none;
-                        padding: 0;
-                        margin: 0;
-                        width: 100%;
-    
-                        .x-navitem {
-                            cursor: default;
-                            position: relative;
-                            list-style: none;
-                            padding: 0;
-                            margin: 0;
-                            outline: none !important;
-                            
-                            .x-navitem-body {
-    
-                                .nav-inner-wrap {
-                                    position: relative;
-                                    overflow: hidden;
-                                    list-style: none;
-                                    max-height: 60px;
-                                    padding: 0 10px;
-                                    display: flex;
-    
-                                    .nav-inner-icon {
-                                        color: $nav-font-color;
-                                        font-size: 24px;
-                                        text-align: center;
-                                        margin-left: 22px;
-                                        display: inline;
-                                        margin-right: 16px;
-    
-                                        &:before {
-                                            line-height: 60px;
-                                        }
-                                    }
-    
-                                    .nav-inner-text {
-                                        font-size: $nav-font-size;
-                                        color: $nav-font-color;
-                                        letter-spacing: 4px;
-                                        text-align: left;
-                                        line-height: 60px;
-                                        height: 60px;
-                                    }
-                                }
-                            }
-                        }
-                        .x-navitem-over {
-                            .x-navitem-body {
-                                background: #65678C;
-
-                                .nav-inner-wrap {
-
-                                    &:before {
-                                        content: ' ';
-                                        position: absolute;
-                                        width: 8px;
-                                        height: 60px;
-                                        background: #34baf6;
-                                        left: 0;
-                                    }
-
-                                    .nav-inner-icon {
-                                        color: $nav-font-color-over;
-                                    }
-
-                                    .nav-inner-text {
-                                        color: $nav-font-color-over;
-                                    }
-                                }
-                            }
-                        }
-                    }
                 }
             }
         }
@@ -128,6 +130,7 @@ $menu-body-background-color: #65678C;
             letter-spacing: 1px;
             display: flex;
             flex-direction: column;
+            outline: none !important;
 
             &:nth-child(2) {
                 .menu-title {

+ 17 - 0
frontend/saas-web/resources/json/navigation.json

@@ -1,7 +1,9 @@
 [{
+    "id": "nav-purchase",
     "text": "采购",
     "iconCls": "x-sa sa-purchase",
     "items": [{
+        "id": "nav-purchase-1",
         "text": "制单",
         "items": [{
             "id": "purchase",
@@ -35,6 +37,7 @@
             "viewType": "purchase-b2b-reconciliation-datalist"
         }]
     }, {
+        "id": "nav-purchase-2",
         "text": "报表",
         "items": [{
             "id": "report-purchase",
@@ -52,9 +55,11 @@
         }]
     }]
 }, {
+    "id": "nav-sale",
     "text": "销售",
     "iconCls": "x-sa sa-tag",
     "items": [{
+        "id": "nav-sale-1",
         "text": "制单",
         "items": [{
             "id": "sale",
@@ -98,6 +103,7 @@
             "viewType": "sale-b2b-recdatalist"
         }]
     }, {
+        "id": "nav-sale-2",
         "text": "报表",
         "items": [{
             "id": "report-sale",
@@ -123,9 +129,11 @@
         }]
     }]
 }, {
+    "id": "nav-stock",
     "text": "库存",
     "iconCls": "x-sa sa-bar",
     "items": [{
+        "id": "nav-stock-1",
         "text": "制单",
         "items": [{
             "id": "appropriationInOut",
@@ -153,6 +161,7 @@
             "viewType": "stock-inventory-editdatalist"
         }]
     }, {
+        "id": "nav-stock-2",
         "text": "报表",
         "items": [{
             "text": "物料出入库明细表",
@@ -169,9 +178,11 @@
         }]
     }]
 }, {
+    "id": "nav-money",
     "text": "资金",
     "iconCls": "x-sa sa-money",
     "items": [{
+        "id": "nav-money-1",
         "text": "制单",
         "items": [{
             "id": "recBbalance",
@@ -205,6 +216,7 @@
             "viewType": "money-fundtransfer-querypanel"
         }]
     }, {
+        "id": "nav-money-2",
         "text": "报表",
         "items": [{
             "text": "应收总账",
@@ -237,9 +249,11 @@
         }]
     }]
 }, {
+    "id": "nav-document",
     "text": "资料",
     "iconCls": "x-sa sa-info",
     "items": [{
+        "id": "nav-document-1",
         "text": "基础资料",
         "items": [{
             "id":"vendor-list-formpanel",
@@ -293,6 +307,7 @@
             "leaf": true
         }]
     }, {
+        "id": "nav-document-2",
         "text": "辅助资料",
         "items": [{
             "config":"vendorkind",
@@ -336,9 +351,11 @@
         }]
     }]
 }, {
+    "id": "nav-setting",
     "text": "设置",
     "iconCls": "x-sa sa-setting",
     "items": [{
+        "id": "nav-setting-1",
         "text": "系统设置",
         "items": [{  
             "id":"sys-manager-formpanel",