使用ExtJs开发MIS系统(1):基于ExtJs的MIS构架设计

1,引言

本系列文章的目标是讲述ExtJs开发MIS的一些设计思路和技巧,本 文假定你已经了解ExtJs,熟悉ExtJs中的主要类且有较强的Js编程能力,缺乏的仅仅是应用的技巧。关于ExtJs的基本内容,请参阅ExtJs官 方网站、Google和园里的相关文章。文中中一些技巧和方法不限于ExtJs,在很多基于富客户端框架——例如SilverLight、Flex等的系 统设计中,都可以使用。

本系列主要包括以下内容:

  1. 基于ExtJs的MIS构架设计。
  2. Js的动态加载。
  3. 使用数据库保存客户端状态。
  4. 轮询。
  5. 使用Action抽象客户端操作。
  6. 客户端MVC。

最后,如果还有精力的话,再写一些ExtJs性能方面的心得。

本文中的例子、代码等来源于真实的的项目,所以恕不能提供完整的代码下载,但会尽量详细的阐述设计思路,并给出关键的代码片段。

欢迎大家交流和指教。

2,客户端的“致富”之路

在SilverLight、Flex等富客户端框架出现以前,系统中通常由服务器负责Html、Css等的生成,也就是负责显示逻辑,客户端与服务器端的交互是按下图的样子:

使用ExtJs开发MIS系统(1):基于ExtJs的MIS构架设计_第1张图片

富客户端将显示逻辑从服务器端转移到客户端。这样服务器端仅仅负责业务逻辑的处理和运算,把处理的结果以纯数据的形式发送给客户端,然后客户端负责具体的显示和交互,这个过程可以通过下面这个图直观的看出来:

使用ExtJs开发MIS系统(1):基于ExtJs的MIS构架设计_第2张图片

以下对图进行一些说明:

1, 图中ExtJs即为客户端框架,当然也可以采用SilverLight等充当。

2, 服务器给出的响应Response,也可以使用JSON等格式,Google就有自己的数据串行化格式:Protocol Buffers。

3, 服务器端关注的仅仅是业务逻辑,而不是数据的表现形式。所以服务器端的响应通常是和客户端无关的,客户端也可以采用WinForm、SilverLight甚至是其他服务等处理端。

4, 理论上讲,我们可以仅仅和ExtJs打交道,而不需要关心具体Html、Css、JavaScript等,然而实际上是不可能的,复杂操作的时候仍免不了 和DOM打交道,而ExtJs在这个时候也能开发提供很大便利。如果使用的SilverLight等其它的、基于浏览器端插件的框架,情况会好一些,但仍 然无法避免和DOM打交道。客户端框架任重而道远……

3,两个世界的对话

服务器和客户端通过Http协议进行交谈,对于一个典型的登录操作来说,客户端发送的Http请求如下(忽略Http头):

POST /User.asmx/Login HTTP/1.1
……

loginId=yuandong&password=mypassword

而服务器端给出的响应是:

HTTP/1.1 200 OK
……



    WrongPassword

对于列表类型的数据,服务器给出类似以下的响应:

HTTP/1.1 200 OK
……



   
        为方便专家使用……
        2008/11/05
        3Top
        关于新系统密码获取问题
        袁冬
   

   
        为适应三校区办公……
        2008/10/16
        1Top关于启用新版的说明
        用户A
   

就像上一节提到的,以上请求和响应,完全是基于数据的,与显示方式无关。另一方面,以上类型的响应可以很容易的使用ExtJs的相关Reader类读取。当然使用JSON等方式传输数据也是可以的,ExtJs也提供了相关的读取类。

4,不是WebService的WebService

从服务器和客户端的通讯方式来看,只要服务器端能够在接收到请求后,给出符合格式的响应,就算OK。我们使用ASP.Net WebService的方式来组织服务器端代码,但不使用SOAP协议,所以叫“不是WebService的WebService”,呵呵。

例如,用户相关的操作——包含同意用户协议、激活、登陆、退出登录等,我们组织为User.asmx,代码如下:

   1:  using ……  
  18:   
  19:  namespace Srims.WebSite
  20:  {
  21:      /// 
  22:      /// 用户相关服务
  23:      /// 
  24:      [WebService(Namespace = "http://srims.ouc.edu.cn/")]
  25:      [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  26:      [ToolboxItem(false)]
  27:      [System.Web.Script.Services.ScriptService]
  28:      public class UserWebService : WebServiceBase
  29:      {
  30:          [WebMethod]
  31:          public void AgreeLicence(string loginID, string password)
  32:          {
  33:              Database
  34:                  .Experts
  35:                  .Get(loginID, password)
  36:                  .AgreeLicence(Database, UserIP);
  37:          }
  38:   
  39:          [WebMethod]
  40:          public void Active(string token)
  41:          {
  42:              Response.WriteXmlHead();
  43:   
  44:              Database
  45:                 .Users
  46:                 .Active(new Guid(token), UserIP)
  47:                 .Show(Response);
  48:          }
  49:   
  50:          [WebMethod]
  51:          public void Login(string loginID, string password)
  52:          {
  53:              Response.WriteXmlHead();
  54:              Database
  55:                 .Users
  56:                 .Login(loginID, password, UserIP)
  57:                 .Show(Response);
  58:          }
  59:   
  60:          [WebMethod]
  61:          public void Logout()
  62:          {
  63:              GetUserLoginLog().Logout(Database);
  64:          }
  65:   
  66:          [WebMethod]
  67:          public void GetExtClientState()
  68:          {
  69:              Response.AppendXmlHeader();
  70:              Response.Write(GetUser().ExtClientState);
  71:          }
  72:   
  73:          [WebMethod]
  74:          public void SetExtClientState(string key, string value)
  75:          {
  76:              GetUser().SetExtClientState(key, value, Database);
  77:          }
  78:      }
  79:  }
 
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

根据以上代码,我们可以使用类似http://localhost/User.asmx/Login这 样的链接方式来访问用户的登陆操作。之所以不使用SOAP协议,是因为要包装请求和响应的信息比较复杂,而且ExtJs本身对SOAP没有提供支持,需要 自行开发包装类,引入了不必要的复杂性,得不偿失。这里需要注意的是,如果想直接以POST和GET的方法调用WebService,需要对 web.config做一些设置,具体来说,就是system.web/webServices节点加入以下内容:

<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
protocols>
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

其实这里使用Url Rewrite更优雅一些,但是由于我们项目本身的一些限制,就不做修改了,有兴趣的朋友可以自己尝试。服务器端不是本文关注的交点,这里就不展开了,相关设计可以参考我的另一个系列文章:微型项目实践。这里我们只要知道客户端与服务器端交互的方式就足够了。

5,客户端架构

客户端基本上使用Js编写,包含少量的Html代码,其它都是通过ExtJs生成。从结构上可以分为三层,最底层是ExtJs,然后是提供各种通用服务的Common Modules,最上面是提供专注于各个功能模块的Function Modules。如下图:

使用ExtJs开发MIS系统(1):基于ExtJs的MIS构架设计_第3张图片 使用ExtJs开发MIS系统(1):基于ExtJs的MIS构架设计_第4张图片

如图所示,Common Modules提供了Js动态加载、状态提供者、轮询、动作等通用功能,这些功能为上层的功能模块提供服务。

从文件夹的组织上也可以一些端倪。文件按照命名空间进行组织,直接位于JavaScript目录下的js适合具体项目无关的。Srims是 项目相关js的顶级命名空间,表示整个系统;用于Common Modules的action.js、formLogin.js、load.js、login.js、main.js等,直接隶属于根命名空间,而 project,common等文件夹则是各个模块。以后的文章中着重讲解这些js。

整个系统中客户端仅有一个Html页面,也就是所谓的OAOP了。页面代码非常简单,仅仅是对Js、Css等文件的引用:

   1:  DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   2:  <html xmlns="http://www.w3.org/1999/xhtml">
   3:      <head>
   4:          <link href="/stylesheets/ext-all.css" rel="stylesheet" type="text/css" />
   5:          <link href="/stylesheets/srims.css" rel="stylesheet" type="text/css" />
   6:          <title>中国海洋大学XXXX管理系统title>
   7:      head>
   8:      <body>
   9:          <div id="DivWrapper">
  10:              <div id="DivLoading" style="text-align: center">
  11:                  正在加载
  12:                  <br/>
  13:                  <img alt="正在加载" src="images/index_loading.gif" />
  14:              div>
  15:              <div id="DivCopyRight">
  16:                  SrimsV0.5 中国海洋大学 并行与分布式计算实验室 Copyright © 2008 
<
a href='#' title="采用SSL加密的安全连接模式">安全模式a>
  17:              div>
  18:              <div id="DivBrowserRecommand">
  19:                  推荐使用谷歌(Google)浏览器操作本系统(<a href='http://www.google.com/chrome' 
title
="点击安装谷歌(Google)浏览器">点击安装a>
  20:              div>
  21:          div>
  22:          <script src="/javascript/ext-base.js" type="text/javascript">
  23:          script>
  24:          
                    
                    

你可能感兴趣的:(技术工具)