背景:项目中使用了树形菜单,单击叶子节点,弹出对应菜单,把返回的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中
}
解决方案:
function MenuId_Panel(){
...
var cm = null;
Ext.Ajax.request({
async: false, //不使用异步
success: function(res){
//使用同步的方法进行列的动态生成;线程阻塞直到请求完成;才能继续执行下面的代码
cm = new Ext.grid.ColumnModel(...res.responseText...);
}
});
//下面的代码
...
}
OK,也能解决问题,换成jQuery.ajax也是同样可行;
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.大公告成.