首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

ExtJS 5 TreePanel實現右鍵菜單:節點操作(增刪改)完整示例

     編輯:程式設計綜合問答

ExtJS 5中為`TreePanel`添加右鍵上下文菜單,需監聽`itemcontextmenu`或`beforecellcontextmenu`事件,動態顯示`Ext.menu.Menu`並綁定節點操作邏輯。本文提供完整可運行代碼結構。

核心實現步驟

  1. 創建`Ext.menu.Menu`實例,定義菜單項(新增、刪除、修改)及處理器。
  2. 監聽TreePanel的`itemcontextmenu`事件(或`cellcontextmenu`)。
  3. 事件處理中:阻止默認瀏覽器右鍵菜單,記錄目標節點,計算菜單顯示位置,調用`menu.showAt(x, y)`。
  4. 菜單項處理器中操作TreeStore(增/刪/改節點)。

完整代碼示例


Ext.define('MyApp.view.MyTree', {
    extend: 'Ext.tree.Panel',
    alias: 'widget.mytree',
    title: '功能樹',
    store: 'MyTreeStore', // 需定義對應Store
    rootVisible: false,
    listeners: {
        // 關鍵事件:節點右鍵
        itemcontextmenu: function(view, record, item, index, e, eOpts) {
            e.stopEvent(); // 阻止瀏覽器默認右鍵菜單
            
            // 可選:只允許特定節點類型顯示菜單
            // if (record.get('leaf')) return; 
            
            // 獲取或創建菜單(單例模式避免重複創建)
            var menu = this.getContextMenu(record);
            if (menu) {
                menu.showAt(e.getXY()); // 在鼠標位置顯示
            }
        }
    },

    // 獲取/創建上下文菜單
    getContextMenu: function(record) {
        if (!this.contextMenu) {
            this.contextMenu = Ext.create('Ext.menu.Menu', {
                items: [
                    {
                        text: '新增子節點',
                        iconCls: 'x-fa fa-plus',
                        handler: 'onAddChildClick', // 對應ViewController方法
                        scope: 'controller'
                    },
                    {
                        text: '修改節點',
                        iconCls: 'x-fa fa-edit',
                        handler: 'onEditClick',
                        scope: 'controller'
                    },
                    {
                        text: '刪除節點',
                        iconCls: 'x-fa fa-trash',
                        handler: 'onDeleteClick',
                        scope: 'controller'
                    }
                ]
            });
        }
        // 將當前右鍵節點掛載到菜單對象,供handler使用
        this.contextMenu.targetRecord = record;
        return this.contextMenu;
    }
});

// ViewController 邏輯分離
Ext.define('MyApp.view.MyTreeController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.mytree',

    onAddChildClick: function(menuItem) {
        var record = menuItem.up('menu').targetRecord;
        record.appendChild({
            text: '新節點 ' + Ext.Date.format(new Date(), 'H:i:s'),
            leaf: true
        });
        record.expand();
    },

    onEditClick: function(menuItem) {
        var record = menuItem.up('menu').targetRecord;
        Ext.Msg.prompt('修改節點', '請輸入新名稱:', function(btn, text) {
            if (btn === 'ok' && text) {
                record.set('text', text);
            }
        }, this, false, record.get('text'));
    },

    onDeleteClick: function(menuItem) {
        var record = menuItem.up('menu').targetRecord;
        Ext.Msg.confirm('確認刪除', '確定要刪除 "' + record.get('text') + '" 及其子節點嗎?', function(btn) {
            if (btn === 'yes') {
                record.erase(); // 或 record.remove(true) 僅移除視圖
            }
        });
    }
});

關鍵點補充

  • 事件選擇:`itemcontextmenu`針對行節點,`cellcontextmenu`針對單元格(需`Ext.grid.Panel`特性)。TreePanel用前者。
  • 阻止默認:`e.stopEvent()`必須調用,否則瀏覽器菜單覆蓋Ext菜單。
  • 菜單復用:將菜單實例緩存在組件屬性(`this.contextMenu`),避免頻繁創建銷毀。
  • 數據持久化:Store配置`autoSync: true`或手動調用`store.sync()`將變更提交後端。
  • 權限控制:在`getContextMenu`中根據`record`數據動態隱藏/顯示菜單項(`menuItem.setHidden(true)`)。

現代ExtJS 6/7+ 寫法提示

推薦使用`ViewController` + `bind` + `reference`架構,菜單定義可提取為獨立`Ext.menu.Menu`子類,通過`viewModel`綁定數據,代碼更解耦可測試。

ExtJS右鍵菜單核心:事件攔截 → 位置計算 → 菜單顯示 → 上下文傳遞 → 業務邏輯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved