• [织梦吧]唯一域名:www.dedecms8.com,织梦DedeCMS学习平台.

当前位置: > 网页制作 > JavaScript >

Web前端开发中的MCRV模式(2)

来源: www.dedecms8.com 编辑:织梦吧 时间:2012-02-07点击:

  3.MCRV设计模式

  综上所述,MVC是解决具有复杂交互界面、代码规模大的应用程序面临代码组织、复用问题的有效设计模式。基于此,本文尝试基于MVC设计思想解决前端开发中的类似问题。然而,在前端页面开发中不能直接套用MVC设计模式。因为,前端开发中的Web页面包含了HTML、CSS、Javascript等多个种类的代码,相对Web后端来说,Web页面整体就是一个负责UI展现、用户本地交互、发送服务请求的大View,与经典MVC及Web后端开发MVC模式中的View皆有不同。因此,需要具体问题具体分析。首先对Web页面中的HTML、CSS、Javascript等代码进一步分析,明确它们的具体功能分类。根据业界提出的Web开发标准,Web页首先被分为了内容-结构-表现-行为几个部分。内容、结构、表现是页面的静态部分,主要负责UI的展现,用户操作指令(键盘、鼠标)的接受,因此,内容、结构、表现属于视图 (View)的范畴。行为主要就是javascript代码,负责对用户操作指令的响应。在复杂ajax应用中, javascript代码的功能一般包括:响应用户指令,执行数据验证/处理、执行客户端交互逻辑,向服务器发送ajax请求,接受并处理服务器返回的数据,根据数据改变UI(向页面结构填充内容数据、变换样式等)。基于模型-视图-控制器分离的思想,Javascript代码中的数据验证/处理、本地业务逻辑计算、向服务器发请求获取数据的功能,对应模型(Model)的功能;响应(翻译)用户操作指令,根据指令执行业务逻辑处理的功能,属于控制器(Controller)的功能;而接受处理过的数据,根据数据修改页面的内容/结构/样式的功能既不属于控制器的功范畴,也不属于模型的功能范畴,这部分代码因为根据数据对View进行呈现(render),可以命名为Renderer(渲染器或呈现器)。根据前述分析,本文提出了MCRV设计模式,如图3所示。阐述如下: M(Model):模型。完成数据验证、数据处理,执行客户端业务逻辑计算,或向服务器发起ajax请求调用服务端逻辑、接受返回的数据,将处理后的数据返回控制器。

  C(Controller):控制器。控制器响应View上的事件,根据事件调度执行模型的业务逻辑,从业务逻辑获取返回数据,调度相应的渲染器(Render)来完成界面展现。在这个过程中控制器会有数据的传递:控制器调用模型中的逻辑时会传送Renderer搜集的数据(form表单各域的name/value、其他控制参数),模型执行逻辑后返回作为执行结果的数据给控制器,控制器根据数据来调用渲染器(renderer)来完成界面呈现(rendering),呈现(rendering)就是修改页面结构、内容和样式的过程。数据传递过程可以用图4表示。

  R(Renderer):渲染器(呈现器)。渲染器被控制器调用,接受从控制器传递的数据,完成对界面的具体渲染。渲染器也负责控件(widget)的初始化,及建立Controller与具体事件的对应关系,事件发生时负责搜集View上的数据传送到Controller。

  V(View):视图。视图是用户最终看到的整个Web界面,由结构、内容、样式(表现)等静态内容共同构成。View由Renderer进行初始化渲染和修改。

  

MCRV开发模式

图3:MCRV开发模式

  

数据传递过程

图4:数据传递过程可以看到在MCRV开发模式中,Controller处于控制中心的位置,Model完成具体的商业逻辑计算以及向后端发起ajax请求返回数据的功能。Controller与Model、Renderer之间的交互本质上数据交互的过程,它们之间存在着一个数据流,如图4所示。因此,制定Controller、Model、Renderer之间的交互接口时,数据格式定义很重要。4.基于MCRV设计模式的Demo

  下面是一个用MCRV模式来开发的Demo页面,页面的功能是用表格展示和修改用户信息。javascript使用了jQuery库。页面界面如图5所示。页面代码在程序清单1中

基于MCRV设计模式的用户管理Demo
图5:基于MCRV设计模式的用户管理Demo程序清单1

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
  2. <html> 
  3. <head> 
  4.     <meta http-equiv="content-type" content="text/html;charset=utf-8"> 
  5.         <meta http-equiv="X-UA-Compatible" content="IE=7" /> 
  6.         <title>MCRV 设计模式 Demo</title> 
  7.         <style type="text/css"> 
  8.             /********表现*********/ 
  9.             table{width:100%;border-collapse: collapse;} 
  10.             td{border: 1px solid black;padding: 2px;} 
  11.             #container {width:800px;margin:0px auto;} 
  12.             #tbUsers{margin:20px auto;} 
  13.             #tbUsers th{background-color: navy;color:white;text-align: center;vertical-align: middle;border:1px solid navy} 
  14.              #tbUsers td{text-align: center;} 
  15.             .editCaption{width:100px;text-align: right;} 
  16.             .buttonMargin{margin:0px 20px;} 
  17.             .buttonContainer{text-align: center;vertical-align: middle;height:50px} 
  18.         </style> 
  19.         <script src="./jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script> 
  20. </head> 
  21. <body> 
  22.     <!-------结构---------> 
  23.     <div id="container"> 
  24.         <table id="tbUsers"> 
  25.             <thead><th>id</th><th>姓名</th><th>年龄</th><th>修改</th></thead> 
  26.             <tbody/> 
  27.         </table> 
  28.         <div style="display: none;" id="dvEditPanel"> 
  29.             <form id="frmModify" name="frmModify"> 
  30.                 <table> 
  31.                 <tr> 
  32.                     <td class="editCaption"> id: </td> 
  33.                     <td><span id="spID"></span></td> 
  34.                 </tr> 
  35.                 <tr> 
  36.                     <td class="editCaption"> 姓名: </td> 
  37.                     <td><input type="text" size="20" id="txtName"/></td> 
  38.                 </tr> 
  39.                 <tr> 
  40.                     <td class="editCaption"> 年龄: </td> 
  41.                     <td><input type="text" size="20" id="txtAge"/></td> 
  42.                 </tr> 
  43.                 <tr> 
  44.                     <td colspan="2"  class="buttonContainer"> 
  45.                         <button id="btnSubmitModify" class="buttonMargin" type="button">提交</button> 
  46.                         <button id="btnCancelModify" class="buttonMargin" type="button">取消</button> 
  47.                     </td> 
  48.                 </tr> 
  49.               </table> 
  50.             </form>  
  51.  
  52.         </div> 
  53.     </div> 
  54.     <script> 
  55.         /***************************行为********************************/  
  56.  
  57.         var UserManagerMCR; 
  58.         $(function() 
  59.         { 
  60.             UserManagerMCR=new MCR(UserController,UserModel,UserRenderer); 
  61.         });  
  62.  
  63.         /* 
  64.          * MCR 三元组 
  65.          */ 
  66.         function MCR(Controller,Model,Renderer) 
  67.         { 
  68.             this.controller=new Controller(); 
  69.             this.model=new Model(); 
  70.             this.renderer=new Renderer(); 
  71.             thisthis.controller.model=this.model; 
  72.             thisthis.controller.renderer=this.renderer; 
  73.             thisthis.model.controller=this.controller; 
  74.             thisthis.renderer.controller=this.controller; 
  75.             if(typeof this.model.init=="function") 
  76.             { 
  77.                 this.model.init(); 
  78.             } 
  79.             if(typeof this.renderer.init=="function") 
  80.             { 
  81.                 this.renderer.init(); 
  82.             } 
  83.             if(typeof this.controller.init=="function") 
  84.             { 
  85.                 this.controller.init(); 
  86.             } 
  87.         }  
  88.  
  89.         /* 
  90.          * 控制器 
  91.          */ 
  92.         function UserController() 
  93.         { 
  94.            this.init=function() 
  95.             { 
  96.                 this.initUserList(); 
  97.             }  
  98.  
  99.             this.initUserList=function() 
  100.             { 
  101.                 var list=this.model.getUserList(); 
  102.                 this.renderer.renderUserList(list); 
  103.             }  
  104.  
  105.             this.beginModify=function(data) 
  106.             { 
  107.                 var user=this.model.getUserByID(data.id); 
  108.                 this.renderer.showModifyUI(user); 
  109.             }  
  110.  
  111.             //提交修改 
  112.             this.submitModify=function(user) 
  113.             { 
  114.                 var result=this.model.modifyUser(user); 
  115.                 if(result.success) 
  116.                 { 
  117.                     var list=this.model.getUserList(); 
  118.                     this.renderer.renderUIWhenSubmitModifySuccess(list); 
  119.                 } 
  120.                 else 
  121.                 { 
  122.                     alert(result.msg); 
  123.                 } 
  124.             }  
  125.  
  126.             //取消修改 
  127.             this.cancelModify=function() 
  128.             { 
  129.                 this.renderer.hideModifyUI(); 
  130.             }  
  131.  
  132.         }  
  133.  
  134.         /* 
  135.          * 模型 
  136.          */ 
  137.         function UserModel() 
  138.         { 
  139.             //模拟的数据,实际应用中经常从服务器获取  
  140.  
  141.            this.init=function() 
  142.            { 
  143.               this.data = [ 
  144.                 {id:0,name:"John",age:22}, 
  145.                 {id:1,name:"Tom",age:30}, 
  146.                 {id:2,name:"Tony",age:25} 
  147.                ]; 
  148.            }  
  149.  
  150.             //获得用户数据列表 
  151.             this.getUserList=function() 
  152.             { 
  153.                 //todo ,可能ajax从后端返回 
  154.                 return this.data; 
  155.             }  
  156.  
  157.             //获得用户数据 
  158.             this.getUserByID=function(id) 
  159.             { 
  160.                 var ix; 
  161.                 $.each(this.data,function(i,item){if(item["id"]==id ) { iix=i; return false;}}); 
  162.                 return this.data[ix]; 
  163.             }  
  164.  
  165.             //修改用户数据 
  166.             this.modifyUser=function(user) 
  167.             { 
  168.                 var result={success:true,msg:"修改成功"}; 
  169.                 //todo,验证参数user 
  170.                 //todo,修改用户数据 
  171.                 $.each(this.data,function(i,item) 
  172.                 { 
  173.                     if(item["id"]==user["id"]) 
  174.                     { 
  175.                         item["name"]=user["name"]; 
  176.                         item["age"]=user["age"] 
  177.                         return false; 
  178.                     } 
  179.                 }); 
  180.                 return result; 
  181.             }  
  182.  
  183.         }  
  184.  
  185.         /* 
  186.          * 渲染器 
  187.          */ 
  188.         function UserRenderer() 
  189.         { 
  190.             this.init=function() 
  191.             { 
  192.                  var me=this
  193.                  $("#btnSubmitModify").click(function() 
  194.                  { 
  195.                      var user={id:$("#spID").text(),name:$("#txtName").val(),age:$("#txtAge").val()}; 
  196.                      me.controller.submitModify(user); 
  197.                  }); 
  198.                  $("#btnCancelModify").click(function() 
  199.                  { 
  200.                      me.controller.cancelModify(); 
  201.                  }); 
  202.                  $("#tbUsers .modify").live("click",function() 
  203.                  { 
  204.                      var id=$(this).attr("uid"); 
  205.                      me.controller.beginModify({"id":id}); 
  206.                  }); 
  207.             }  
  208.  
  209.             this.renderUserList=function(list) 
  210.             { 
  211.                 var htm=[]; 
  212.                 for(var ix=0;ix<list.length;ix++) 
  213.                 { 
  214.                     htm.push("<tr><td>" +list[ix]["id"]+"</td>" +"<td>"+list[ix]["name"]+"<td>"+list[ix]["age"]+"</td>
  215.                         +"<td>"+"<a class='modify' href='javascript:void(0)' uid='"+list[ix]["id"]+"'>修改</a></td>"+"</tr>"); 
  216.                 } 
  217.                 $("#tbUsers").children("tbody").html(htm.join("")); 
  218.             }  
  219.  
  220.             this.showModifyUI=function(user) 
  221.             { 
  222.                 $("#dvEditPanel").show(); 
  223.                 $("#spID").text(user["id"]); 
  224.                 $("#txtName").val(user["name"]); 
  225.                 $("#txtAge").val(user["age"]); 
  226.             }  
  227.  
  228.             this.hideModifyUI=function() 
  229.             { 
  230.                 document.frmModify.reset(); 
  231.                 $("#dvEditPanel").hide(); 
  232.             }  
  233.  
  234.             this.renderUIWhenSubmitModifySuccess=function(list) 
  235.             { 
  236.                 this.hideModifyUI(); 
  237.                 this.renderUserList(list); 
  238.             } 
  239.         } 
  240.     </script> 
  241. </body> 
  242. </html> 

About D8

  • ©2014 织梦吧(d8) DedeCMS学习交流平台
  • 唯一网址 www.DedeCMS8.com 网站地图
  • 联系我们 1170734538@qq.com ,  QQ