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;
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然后压缩):
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<!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.BLANK_IMAGE_URL = '../Scripts/ext/resources/images/default/s.gif';
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里的子页写死):
new Ext.Panel({
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;
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库
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<!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加载方式:
function Main_Index() {
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场景设计交织在一起,比较复杂,我也不可能讲的太细,怕大家看不明白...
希望大家留言。