ExtJs 使用Promise async await

ExtJs 使用Promise async await

背景:项目中使用了树形菜单,单击叶子节点,弹出对应菜单,把返回的Panel对象放到主面板TabPanel中,实现菜单动态加载;现在遇到这么一个问题,如果我需要加载返回的Panel对象带有grid,并且这个grid的列需要从数据库里去拿;

//点击叶子菜单将会请求Ajax返回一个方法,调用这个方法获取真正的Ext面板对象

function MenuId_Panel(){

    //问题是这个这里的column数组是需要从数据库中动态获取
    var cm = new Ext.grid.ColumnModel([...]);

    var sm = new Ext.grid.RowSelectionModel({
        header: "",
        singleSelect: true
    });

    var grid = new Ext.grid.GridPanel({
        store: store,
        cm: cm,
        sm: sm
    });

    var query_panel = new Ext.Panel({
        id: "MenuId_Btn_Panel",
        layout: 'fit',
        items: [grid]
    });

    return query_panel;
}

...

//树形菜单单击事件
function loadPanel() {
    var query_panel = MenuId_Panel();//获取返回的Ext面板对象
    tabPanel.add(query_panel);//把面板加入到TabPanel中
}

解决方案:

  • 使用Ajax请求获取Column数据,并且增加配置项: async: false;那么上面的代码就会变成:
function MenuId_Panel(){
    ...

    var cm = null;

    Ext.Ajax.request({
        async: false, //不使用异步
        success: function(res){
            //使用同步的方法进行列的动态生成;线程阻塞直到请求完成;才能继续执行下面的代码
            cm = new Ext.grid.ColumnModel(...res.responseText...);
            
        }
    });
    
    //下面的代码
    ...
}

OK,也能解决问题,换成jQuery.ajax也是同样可行;

  • 使用async|await|Promise

1) 首先,创建全局的ExtPromise方法

//全局封装ExtPromise对象
const ExtPromise = (url, params) => {
    return new Promise((resovle, reject) => {
        Ext.Ajax.request({
            url: url,
            params: params,
            success: res => {
                resovle(res);
            },
            failure: res => {
                reject(res);
            }
        });
    });
}

2) 修改MenuId_Panel方法

async function MenuId_Panel(){
    ...

    var cm = null;

    //封装了一下initColumns方法
    let initColumns = async() => {
	    let newCm = await ExtPromise("urlPath", {...yourParams...}).then(res => {
	        let tmpCm = new Ext.grid.ColumnModel([...res.responseText...])
                //需要使用Promise.resolve方法,才能返回tmpCm,否则默认返回Promise对象
		        return Promise.resolve(tmpCm);
    		});
	    return newCm;
    }

    cm = await initColumns();//当浏览器执行到这一步时会阻塞,直到initColumns返回对象;
    
    //下面的代码
    ...
}

3) 当然相应的叶子节点的单机事件也要修改为async,只有在async的方法中,才能使用await;

//树形菜单单击事件
async function loadPanel() {
    var query_panel = await MenuId_Panel();//获取返回的Ext面板对象
    tabPanel.add(query_panel);//把面板加入到TabPanel中
}

OK.大公告成.

你可能感兴趣的:(extjs)