如果使用iframe的方式,会导致每个页面都要重复地加载ext的相关类库,导致服务器和网络承受更大的压力。由于每个页面加载的都是一样的ext类库,如果能实现只加载一次,之后每个页面都能使用这个ext类库,将解决以上提出的问题。
以下是我在使用ext4.2版本下的解决办法,主要原理是通过tab的autoload的方式载入tab页面。由于公司项目目前用的就是这个版本的ext,也由于时间关系,没有对其他版本的ext进行测试,不过我觉得原理都是差不多的,只是实现的方式有些区别。
废话不多说,直接上代码,O(∩_∩)O~,(想必很多人和我一样都喜欢这种方式吧)
1、首先,定义总的页面框架的js文件:border.js
Ext.require(['*']);
Ext.onReady(function() {
var store = Ext.create('Ext.data.TreeStore', {
proxy : {
type : 'ajax',
url : 'system/js/menu.json'
},
root : {
text : 'Ext JS',
id : 'src',
expanded : true
},
folderSort : true,
sorters : [{
property : 'menuSort',
direction : 'ASC'
}]
});
var coamanytreepanel = Ext.create('Ext.tree.Panel', {
region : "center",
store : store,
hideHeaders : true,
rootVisible : false,
listeners : {
'itemclick' : function(view, record, item, index, e) {
//点击菜单时,执行main.js里的addTab方法。
//传递的参数包括当前点击节点的id,url,文本信息text,是否是叶子leaf。
addTab(record.raw.id,record.raw.url,record.raw.text,record.raw.leaf);
}
}
});
coamanytreepanel.on('beforeload', load, this);
//点击菜单项时加载的json
function load(store, opration) {
pid = opration.node.data.id
store.proxy.url = 'system/js/' + pid + '.json';
}
var mymain = new Ext.Viewport({
layout : {
type : 'border',
padding : 5
},
defaults : {
split : true
},
items : [Ext.create('Ext.panel.Panel', {
title : "",
id : "aa",
region : "north",
height : 90,
collapsible : false,
html:'学习,学习'
}), Ext.create('Ext.panel.Panel', {
id : "westpanel",
title : "菜单栏",
split : true,
layout : 'border',
collapsible : true,
region : "west",
width : 200,
items : [coamanytreepanel]
}), {
xtype : 'tabpanel',
id : 'tab',
layout:'fit',
activeTab : 0,
region : 'center',
items : [{
title : '欢迎界面',
id : 'index',
layout:'fit',
closable : false,
items : [Ext.create('Ext.panel.Panel', {
html : '欢迎使用'
})]
}]
}]
});
});
可以看到上面的菜单栏里定义了点击菜单项的事件: 'itemclick', 点击后执行addTab方法,该方法在main.js定义。
2、main.js中定义了每次点击菜单项时生成显示的页面,其代码如下:
function addTab(id, link, name,isLeaf){
// alert("ID:"+id+",链接:"+link+",名称:"+name+",是否叶子:"+isLeaf);
if(isLeaf){
var tabId = "tab-"+id;
var tabTitle = name;
var tabLink = link;
var centerpanel = Ext.getCmp("tab");
var tab = centerpanel.getComponent(tabId);// 得到tab组件
var subMainId = 'tab-'+id+'main';
if(!tab){
tab = centerpanel.add(new Ext.Panel({
id:tabId,
title:tabTitle,
autoScroll:true,
iconCls:'tabIconCss',
border:false,
closable:true,
layoutOnTabChange:true,
loader:{
url:tabLink,
autoLoad:true,
scripts: true,
timeout: 9000,
params:{subMainId: subMainId}//传动jsp页面,是对应页面的panel的id唯一
},
listeners : {
'resize' : function(component, width, height, oldWidth, oldHeight, eOpts) {
var tabs = centerpanel.items.items;
var currentPanel = Ext.getCmp(subMainId+"-js");//通过ID取得当前页面的panel
if(currentPanel){
//取得引入页面的高度和宽度
var h = Ext.getCmp('tab').getActiveTab().getEl().getHeight();
var w = Ext.getCmp('tab').getActiveTab().getEl().getWidth();
currentPanel.setWidth(w);
currentPanel.setHeight(h);
}
}
}
}));
centerpanel.setActiveTab(tab);
}else{
centerpanel.setActiveTab(tab);
}
}
}
可以看到,该文件只定义了一个方法。这个方法里,我个人觉得比较重要的部分都做了备注。
3、点击了菜单项后,调用addTab方法后,直接引用了对应的jsp页面,这里使用person.jsp来举例,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
String mainName = (String)request.getParameter("subMainId");
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
var mainName_js = "<%=mainName%>";
</script>
<script type="text/javascript" src="<%=path %>/system/js/person.js"></script>
</head>
<body>
<div id="<%=mainName%>-jsp" style='height:100%;width:100%'></div>
</body>
</html>
4、最后jsp页面回去调用对应的js文件。本例中perosn.jsp调用的就是person.js文件,其内容如下:
Ext.onReady(function(){
Ext.define('Person',{
extend:'Ext.data.Model',
idProperty:'id',
fields:[{
name:'name'
},{
name:'age'
},{
name:'class'
}]
});
var personStroe = Ext.create('Ext.data.Store',{
pageSize:10,
model:'Person',
proxy:{
type:'ajax',
url:'system/js/person.json',
reader:{
root:'personPages',
totalProperty:'totalProperty'
}
}
});
var personGrid = Ext.create('Ext.grid.Panel',{
store:personStroe,
selModel : Ext.create('Ext.selection.CheckboxModel', {injectCheckbox : 1}),
autoScroll:true,
tbar:[{
labelWidth : 70,
xtype : 'textfield',
fieldLabel : "名称"
}],
columns:[{
text : '序号',
xtype : 'rownumberer',
width : 40,
sortable : false,
align : 'center'
}, {
text : '名字',
width : 125,
sortable : true,
dataIndex : 'name'
}, {
text : '年龄',
width : 125,
sortable : true,
dataIndex : 'age'
}, {
text : '班级',
width : 125,
sortable : true,
dataIndex : 'class'
}],
bbar : Ext.create('Ext.PagingToolbar', {
store : personStroe,
dock : 'bottom',
firstText : '第一页',
lastText : '最后一页',
prevText : '前一页',
nextText : '下一页',
refreshText : '刷新',
beforePageText : '第',
afterPageText : '页,共{0}页',
displayInfo : true,
displayMsg : '第{0}-{1}条,共{2}条',
emptyMsg : '没有记录'
}),
viewConfig : {
forceFit : true,
stripeRows : true
}
});
personStroe.loadPage(1);
//定义一个panel,renderTo到对应的JSP页面中定义的ID,
//该panel中的id,也对应JSP中的ID,以便main.js中取得到该ID
//使得可以在触发resize事件时,得到改panel
Ext.create('Ext.panel.Panel',{
layout:'fit',
height:Ext.get(mainName_js+"-jsp").getHeight(),
width:Ext.get(mainName_js+"-jsp").getWidth(),
renderTo:mainName_js+"-jsp",
id:mainName_js+'-js',
autoScroll:true,
items:[personGrid]
});
});
好了,这样就完成了我们的功能了。