Asp.Net大型项目实践(9)-ExtJs实现系统框架页(非iframe,附源码,在线demo)
本篇我们来做系统的框架页,并用EXT的“load”方式实现单页渲染。使整个应用程序就是一个单页,而非iframe实现的框架页,这样那些引用的繁杂JS库只需加载一次即可,而无需每个功能页都重新加载一边所有引用JS,从而大大提高了效率,杜绝了内存溢出错误。国际惯例先看效果图:
在线Demo:http://218.60.8.35:1234/(按登录按钮直接进入,如果你路由器禁用了1234端口可能访问不到哈)
是不是很漂亮呢?因为有了强悍的EXTJS,我们不需要搞美工,CSS,HTML这些繁杂的东西就能实现出来。左边的动态菜单树是通过权限配置出的,由于我们还没有讲到权限管理,所以这里左边的菜单树暂时不实现。上面的那些按钮点击的具体功能也暂不实现。
首先我们新建一个文件MasterPage.cs,和上篇一样只有一个简单的名为MasterPage的Action返回View即可
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Demo.HIS.MVC.CommonSupport;
namespace Demo.HIS.MVC.Controllers
{
public partial class MainController : BaseController
{
public ActionResult MasterPage()
{
return View();
}
}
}
同样在Views文件下的Main文件夹下新建文件MasterPage.aspx,里面包含了整个系统所需的所有JS,就像前面说的这些CSS和JS库只需要在这里加载一次即可,以后的具体功能页都不需要加了。(可以看到加载CSS和JS文件非常多,这是在开发阶段...在交付客户使用的时候可以整理成一个JS然后压缩):
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head runat ="server" >
< link href ="http://www.cnblogs.com/Scripts/ext/resources/css/ext-all.css" rel ="stylesheet" type ="text/css" />
< link href ="http://www.cnblogs.com/Scripts/ext-ux/css/ux-all.css" rel ="stylesheet" type ="text/css" />
< link href ="http://www.cnblogs.com/Content/Site.css" rel ="stylesheet" type ="text/css" />
< link href ="http://www.cnblogs.com/Content/IconCls.css" rel ="stylesheet" type ="text/css" />
< link href ="http://www.cnblogs.com/Scripts/ext-ux/SuperBoxSelect/superboxselect.css" rel ="stylesheet" type ="text/css" />
< link href ="http://www.cnblogs.com/Scripts/ext-ux/TreeGrid/TreeGrid.css" rel ="stylesheet" type ="text/css" />
< link href ="http://www.cnblogs.com/Scripts/ext-ux/GridSummary/GridSummary.css" rel ="stylesheet" type ="text/css" />
< script src ="http://www.cnblogs.com/Scripts/ext/adapter/ext/ext-base.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/ext/ext-all.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/ext/src/locale/ext-lang-zh_CN.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/RemoteValidator.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/ext-ux/ux-all.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/RowEditorOverride.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/FilterOverride.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/Ext.data.StoreOverride.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/ComboBoxOverride.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/ext-ux/SuperBoxSelect/SuperBoxSelect.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/ext-ux/TreeGrid/TreeGrid.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/ext-ux/GridSummary/GridSummary.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/Ext.form.Action.LoadOverride.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/JsHelper.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/CustomExt.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/DomainControlers.js" type ="text/javascript" ></ script >
< script src ="http://www.cnblogs.com/Scripts/Main/MasterPage.aspx.js" type ="text/javascript" ></ script >
< title > 代码如尿崩MIS </ title >
</ head >
< body >
< div ></ div >
</ body >
</ html >
接下来是最主要的MasterPage.aspx.js文件:
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = ' title ' ;
var ALL_PAGESIZE_SETTING = 15 ; // 这里设置系统分页数的全局变量
function Main_MasterPage() {
// 居顶工具栏
var topBar = new Ext.Toolbar({
region : ' north ' ,
border : false ,
split : true ,
height : 26 ,
minSize : 26 ,
maxSize : 26 ,
items : [{
xtype : ' tbbutton ' ,
text : " 代码如尿崩MIS " ,
cls : ' x-btn-text-icon ' ,
icon : ' /Content/icons/house.png ' ,
disabled : true ,
disabledClass : ''
}, " - " , {
xtype : ' tbbutton ' ,
text : " 心脏外科 " ,
cls : ' x-btn-text-icon ' ,
icon : ' /Content/icons/layers.png ' ,
disabled : true ,
disabledClass : ''
}, " - " , {
xtype : ' tbbutton ' ,
text : " 王二麻 " ,
cls : ' x-btn-text-icon ' ,
icon : ' /Content/icons/user.png ' ,
disabled : true ,
disabledClass : ''
}, " -> " , " - " , {
xtype : " tbbutton " ,
minWidth : 80 ,
text : " 刷新当前页 " ,
cls : " x-btn-text-icon " ,
icon : " /Content/icons/arrow_refresh.png " ,
handler : function (btn, e) {
var tab = tabMain.getActiveTab();
tab.removeAll( true );
tab.getUpdater().refresh();
}
}, " - " , {
xtype : " tbbutton " ,
minWidth : 80 ,
text : " 全部关闭 " ,
cls : " x-btn-text-icon " ,
icon : " /Content/icons/stop.png " ,
handler : function (btn, e) {
tabMain.items.each( function (item) {
if (item.closable) {
tabMain.remove(item, true );
}
})
}
}, " - " , {
xtype : " tbbutton " ,
minWidth : 80 ,
text : " 设置为常用页 " ,
cls : " x-btn-text-icon " ,
icon : " /Content/icons/asterisk_yellow.png " ,
handler : function (btn, e) {
}
}, " - " , {
xtype : " tbbutton " ,
minWidth : 80 ,
text : " 修改密码 " ,
cls : " x-btn-text-icon " ,
icon : " /Content/icons/key.png " ,
handler : function (btn, e) {
}
}, " - " , {
xtype : " tbbutton " ,
minWidth : 80 ,
text : " 帮助 " ,
cls : " x-btn-text-icon " ,
icon : " /Content/icons/lightbulb.png " ,
handler : function (btn, e) {
}
}, " - " , {
xtype : " tbbutton " ,
minWidth : 80 ,
text : " 注销 " ,
cls : " x-btn-text-icon " ,
icon : " /Content/icons/lock_go.png " ,
handler : function (btn, e) {
}
}, " - " , {
xtype : " tbbutton " ,
minWidth : 80 ,
text : " 退出 " ,
cls : " x-btn-text-icon " ,
icon : " /Content/icons/door_out.png " ,
handler : function (btn, e) {
}
}]
});
// 左边的菜单
var menu = new Ext.tree.TreePanel({
title : ' 功能菜单 ' ,
region : " west " ,
autoScroll : true ,
enableTabScroll : true ,
collapsible : true ,
collapsed : true ,
iconCls : ' plugin ' ,
split : true ,
rootVisible : false ,
lines : false ,
width : 220 ,
minSize : 220 ,
maxSize : 220 ,
root : new Ext.tree.AsyncTreeNode({
id : ' 0 ' , // 注意这个0是约定
level : ' 0 ' ,
expanded : true ,
text : ' 菜单 ' ,
leaf : false
})
});
// 主显示区
var tabMain = new Ext.TabPanel({
id : " Main_MasterPage_TabMain " ,
region : " center " ,
autoScroll : true ,
enableTabScroll : true ,
activeTab : 0 ,
onTitleDbClick : function (e, target, o) {
var t = this .findTargets(e);
if (t.item && t.item.closable) {
if (t.item.fireEvent( ' beforeclose ' , t.item) !== false ) {
t.item.fireEvent( ' close ' , t.item);
this .remove(t.item);
}
}
},
items : [ new Ext.Panel({
id : ' tab-0001 ' ,
title : ' 首页 ' ,
autoScroll : true ,
layout : ' fit ' ,
border : false ,
iconCls : ' house ' ,
autoLoad : {
url : ' /Main/Index ' ,
scope : this ,
scripts : true ,
text : ' 页面加载中,请稍候.... '
}
})]
});
// 居底工具栏
var footBar = new Ext.ux.StatusBar({
region : " south " ,
items : [ " -> " , " 弦哥版权所有 " ]
});
// 创建框架
new Ext.Viewport({
id : " Main_MasterPage_ViewPort " ,
layout : ' border ' ,
items : [tabMain, topBar, footBar, menu]
});
}
Ext.onReady( function () {
Main_MasterPage();
});
上面的代码基本就是个框架布局没啥好说的,唯一需要注意的是下面的代码 比如我们要在tab里加一个叫“首页”的子页面(因为没有菜单,所以暂时把tab里的子页写死):
id : ' tab-0001 ' ,
title : ' 首页 ' ,
autoScroll : true ,
layout : ' fit ' ,
border : false ,
iconCls : ' house ' ,
autoLoad : {
url : ' /Main/Index ' ,
scope : this ,
scripts : true ,
text : ' 页面加载中,请稍候.... '
}
})
注意autoLoad属性,这样实现了在单页中动态渲染了需要加载的子页面,url:'/Main/Index'就是要请求子页面的URL。
下面我们简单实现一下/Main/Index这个子页:
新建Index.cs文件
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Demo.HIS.MVC.CommonSupport;
namespace Demo.HIS.MVC.Controllers
{
public partial class MainController : BaseController
{
public ActionResult Index()
{
return View();
}
}
}
新建文件Index.aspx,虽然我们将在这个子页实现一些EXTJS的功能,但是这里除了引用Index.aspx.js这个本页对应的js外,无需引用其他任何CSS和JS库
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head runat ="server" >
< title > Index </ title >
< script src ="http://www.cnblogs.com/Scripts/Main/Index.aspx.js" type ="text/javascript" ></ script >
</ head >
< body >
< div >
</ div >
</ body >
</ html >
最后是Index.aspx.js的代码,简单实现一个EXT按钮和提示框来验证我们的load加载方式:
var btn = new Ext.Button({
text : ' 我是一个Ext按钮 ' ,
handler : function () {
Ext.MessageBox.alert( ' 提示框 ' , ' 代码如尿崩,谁与我争疯! ' );
}
});
var panel = new Ext.Panel({
title : ' 一个panel ' ,
items : [btn]
});
JsHelper.ExtTabDoLayout(panel); // 注意这里把panel组件加到当前的tabpanel里
}
Main_Index(); // 执行方法
最后效果如下:
这两篇关于EXT的内容都比较简单,没有涉及到EXTJS与后台Asp.net MVC的交互,下篇准备开始正经介绍EXTJS与后台的各种复杂交互,这里向大家征求一下意见,后面的篇章我想有两种方式去写:
第一种:先把MIS中的EXT结合后台的每个典型UI场景(如:下拉框绑定,表格绑定,表单提交等...)独立的系统的讲
第二种:直接按业务应用功能场景实现(如:字典管理,用户管理,角色管理,菜单管理...等,计划是完整的实现整个权限管理)去讲,这样虽然也会涉及到所有的典型UI场景,但各种UI场景设计交织在一起,比较复杂,我也不可能讲的太细,怕大家看不明白...
希望大家留言。
转载请注明本文地址:Asp.Net大型项目实践(9)-ExtJs实现系统框架页(非iframe,附源码,在线demo)