声明:原创文章,转载请留出处
先声明,动态载入的是一个类定义文件,比如,你扩展的窗口或诸如此类,可以很复杂,比如像我这样,就是某个界面.
难点在于:
使和ajax.request请求得到的脚本文件,被eval后,再用new产生组件,但问题在于这个生成的组件,却是无法传递出Request范围的,这是很郁闷的事,不然的话,就顺理成章的多.
Ext.ajax.request的返回值是无法改变的,应在Success回调函数中来运行组件文件,并生成组件.
很多人试着想把success回调函数中生成的值赋给全局变量,这样,就相当于把AJAX.REQUEST中一些结果带出来了.但事实上,经过N百回测试,以及GOOGLE搜索,问的人多,答案就没有,EXT官网和一些外国技术站点里,也没有人给出答案.
幸好JS有一个东东,Callback函数,这玩意真像C的函数指针,你把一个函数赋给一个变量,然后就可以用它来调用,并且传递参数给它,让这个回调函数做一些操作.问题就在这儿了,关键是,这个回调函数可以是另一个模块中定义的,这就妙了.
我的LoadModule函数就用了这点,LoadModule的调用者,传递一个container和一个回调函数,Loadmodule生成组件,并将其加入到container中,同时,将生成的组件作为参数Post给调用者提供的回调函数,这样,调用者就可以根据需要做一些操作,我的代码中,用loadmodule生成一个panel,将其加入到tabpanel中,而回调函数则将此panel设为活动的.整个过程中,调用者和被调用者保持了各自的独立性.
LoadModule方法:

Ext.apply(Ext, {
loadModule: function(config){
var container = config.container;
var url = config.url;
var params = config.params ||{};
var myMask = new Ext.LoadMask(Ext.getBody(), {
msg: "Loading..."
});
myMask.show();
Ext.Ajax.request({
method: 'GET',
disableCaching: true,
url: url,
success: function(response){
var module = eval(response.responseText);
var comp = new module(params);
container.add(comp);
//回调函数,得到该组件
if (config.callBack)
config.callBack(comp);
},
failure: function(response){
Ext.MessageBox.alert("Error", "Load Module Failure!");
},
scope: this
});
myMask.hide();
}
});
某个自定义组件代码

category_UI = Ext.extend(Ext.Panel, {
constructor: function(config){
config = config ||
{};
category_UI.superclass.constructor.call(this, config);
},
initComponent: function(){
var datastore = new Ext.data.JsonStore({
url: "/data/category.asp",
requestMethod: "GET",
root: "data.records",
remoteSort: false,
autoLoad: true,
totalProperty: "data.total",
idProperty: "id",
sortInfo: {
field: "id",
direction: "DESC"
},
fields: [{
name: "id",
type: "int"
}, {
name: "name"
}, {
name: "type"
}, {
name: "description"
}]
});
var grid = new Ext.grid.GridPanel({
store: datastore,
enableDragDrop: false,
border: false,
iconCls: "icon-grid",
autoHeight: true,
autoWidth: true,
header: false,
frame: false,
initload: true,
autoExpandColumn: "Description",
loadMask: true,
layout: 'fit',
viewConfig: {
forceFit: true,
emptyText: "No Records"
},
bbar: [{
xtype: "button",
text: "New Category",
enableToggle: false,
handler: function(btn, e){
}
}],
columns: [{
header: "ID",
sortable: true,
dataIndex: "id",
hideable: false,
width: 40
}, {
header: "Category",
sortable: true,
dataIndex: "name",
hideable: false,
width: 80
}, {
header: "Type",
sortable: true,
dataIndex: "type",
width: 80,
hideable: true
}, {
header: "Description",
sortable: true,
dataIndex: "description",
hideable: false
}],
stripeRows: true
});
Ext.apply(this, {
items: [grid]
});
category_UI.superclass.initComponent.call(this, arguments);
}
});
constructor: function(config){
config = config ||
{};
category_UI.superclass.constructor.call(this, config);
},
initComponent: function(){
var datastore = new Ext.data.JsonStore({
url: "/data/category.asp",
requestMethod: "GET",
root: "data.records",
remoteSort: false,
autoLoad: true,
totalProperty: "data.total",
idProperty: "id",
sortInfo: {
field: "id",
direction: "DESC"
},
fields: [{
name: "id",
type: "int"
}, {
name: "name"
}, {
name: "type"
}, {
name: "description"
}]
});
var grid = new Ext.grid.GridPanel({
store: datastore,
enableDragDrop: false,
border: false,
iconCls: "icon-grid",
autoHeight: true,
autoWidth: true,
header: false,
frame: false,
initload: true,
autoExpandColumn: "Description",
loadMask: true,
layout: 'fit',
viewConfig: {
forceFit: true,
emptyText: "No Records"
},
bbar: [{
xtype: "button",
text: "New Category",
enableToggle: false,
handler: function(btn, e){
}
}],
columns: [{
header: "ID",
sortable: true,
dataIndex: "id",
hideable: false,
width: 40
}, {
header: "Category",
sortable: true,
dataIndex: "name",
hideable: false,
width: 80
}, {
header: "Type",
sortable: true,
dataIndex: "type",
width: 80,
hideable: true
}, {
header: "Description",
sortable: true,
dataIndex: "description",
hideable: false
}],
stripeRows: true
});
Ext.apply(this, {
items: [grid]
});
category_UI.superclass.initComponent.call(this, arguments);
}
});
动态构造界面范例

Ext.onReady(function(){
Ext.QuickTips.init();
//构造右侧主界面
var tabs = new Ext.TabPanel({
xtype: "tabpanel",
region:"center",
activeTab: 0,
margins: "5 5 5 0",
deferredRender: false,
contextmenu: false,
layoutOnTabChange: true,
listeners: {
"contextmenu": function(tabpanel, tab, e){
if (!this.contextmenu) {
this.contextmenu = new Ext.menu.Menu([{
text: 'Close',
handler: function(){
if (tabs.ctxItem.closable)
tabs.remove(tabs.ctxItem);
}
}, {
text: 'Close Other',
handler: function(){
tabs.items.each(function(item){
if (item.closable && item != tabs.ctxItem)
tabs.remove(item);
});
}
}]);
}
e.stopEvent();
this.ctxItem = tab;
this.contextmenu.showAt(e.getPoint());
}
},
items: [{
id: "help",
title: "Overview",
closable: false,
autoHeight: true,
autoLoad: {
url: "/ui/help/",
scripts: true,
timeout: 90,
nocache: false
}
}]
});
var mainMenu = new Ext.tree.TreePanel({
region: "west",
width: 180,
minSize:160,
maxSize:200,
margins: "5 0 5 5",
title: 'Menu',
rootVisible: false,
lines: true,
autoScroll: true,
singleExpand: false,
useArrows: true,
loader: {url: '/data/menu.asp',requestMethod:"GET"},
root: new Ext.tree.AsyncTreeNode({expanded:true}),
listeners: {
"click": function(node, event){
event.stopEvent();
var href = node.attributes["href"];
if (href != undefined && node.leaf) {
Ext.loadModule({
container: tabs,
url: href + "index.asp",
params: {
id: "view" + node.id,
title: node.text,
container: tabs,
closable:true,
autoHeight:true,
autoWidth:true,
border:false,
frame:false
},
callBack:function(ctrl)
{
tabs.setActiveTab(ctrl);
s=ctrl;
}
});
tabs.doLayout();
}
}
}
});
var mainView = new Ext.Viewport({
layout: "border",
title: "Document Control System",
autoHeight: true,
autoWidth: true,
defaults: {
split: true
},
items: [mainMenu, tabs],
renderTo: Ext.getBody()
});
mainMenu.expandAll();
})
Ext.QuickTips.init();
//构造右侧主界面
var tabs = new Ext.TabPanel({
xtype: "tabpanel",
region:"center",
activeTab: 0,
margins: "5 5 5 0",
deferredRender: false,
contextmenu: false,
layoutOnTabChange: true,
listeners: {
"contextmenu": function(tabpanel, tab, e){
if (!this.contextmenu) {
this.contextmenu = new Ext.menu.Menu([{
text: 'Close',
handler: function(){
if (tabs.ctxItem.closable)
tabs.remove(tabs.ctxItem);
}
}, {
text: 'Close Other',
handler: function(){
tabs.items.each(function(item){
if (item.closable && item != tabs.ctxItem)
tabs.remove(item);
});
}
}]);
}
e.stopEvent();
this.ctxItem = tab;
this.contextmenu.showAt(e.getPoint());
}
},
items: [{
id: "help",
title: "Overview",
closable: false,
autoHeight: true,
autoLoad: {
url: "/ui/help/",
scripts: true,
timeout: 90,
nocache: false
}
}]
});
var mainMenu = new Ext.tree.TreePanel({
region: "west",
width: 180,
minSize:160,
maxSize:200,
margins: "5 0 5 5",
title: 'Menu',
rootVisible: false,
lines: true,
autoScroll: true,
singleExpand: false,
useArrows: true,
loader: {url: '/data/menu.asp',requestMethod:"GET"},
root: new Ext.tree.AsyncTreeNode({expanded:true}),
listeners: {
"click": function(node, event){
event.stopEvent();
var href = node.attributes["href"];
if (href != undefined && node.leaf) {
Ext.loadModule({
container: tabs,
url: href + "index.asp",
params: {
id: "view" + node.id,
title: node.text,
container: tabs,
closable:true,
autoHeight:true,
autoWidth:true,
border:false,
frame:false
},
callBack:function(ctrl)
{
tabs.setActiveTab(ctrl);
s=ctrl;
}
});
tabs.doLayout();
}
}
}
});
var mainView = new Ext.Viewport({
layout: "border",
title: "Document Control System",
autoHeight: true,
autoWidth: true,
defaults: {
split: true
},
items: [mainMenu, tabs],
renderTo: Ext.getBody()
});
mainMenu.expandAll();
})