一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Web前端開發(fā)中的MCRV模式

 weiledream 2011-10-14
針對前端開發(fā)中基于ajax的復(fù)雜頁面開發(fā)所面臨的代碼規(guī)模大,難以組織和維護(hù),代碼復(fù)用性、擴(kuò)展性和適應(yīng)性差等問題,本文嘗試以MVC思想為基礎(chǔ),結(jié)合Web前端開發(fā)中內(nèi)容-結(jié)構(gòu)-表現(xiàn)-行為相分離的開發(fā)標(biāo)準(zhǔn),提出一種將Web頁面代碼分為視圖(View,頁面靜態(tài)部分,包括內(nèi)容、結(jié)構(gòu)、表現(xiàn))、模型(Model,負(fù)責(zé)數(shù)據(jù)緩存、數(shù)據(jù)校驗(yàn)與本地邏輯處理、發(fā)起ajax請求)、控制器(Controller,負(fù)責(zé)用戶和系統(tǒng)事件響應(yīng)、模型和呈現(xiàn)器調(diào)度)、呈現(xiàn)器(Renderer,對視圖的渲染,控制器與事件的綁定、數(shù)據(jù)搜集)的頁面開發(fā)新模式,并基于此模式提出了一個(gè)開發(fā)框架原型。

  摘要

  針對前端開發(fā)中基于ajax的復(fù)雜頁面開發(fā)所面臨的代碼規(guī)模大,難以組織和維護(hù),代碼復(fù)用性、擴(kuò)展性和適應(yīng)性差等問題,本文嘗試以MVC思想為基礎(chǔ),結(jié)合Web前端開發(fā)中內(nèi)容-結(jié)構(gòu)-表現(xiàn)-行為相分離的開發(fā)標(biāo)準(zhǔn),提出一種將Web頁面代碼分為視圖(View,頁面靜態(tài)部分,包括內(nèi)容、結(jié)構(gòu)、表現(xiàn))、模型(Model,負(fù)責(zé)數(shù)據(jù)緩存、數(shù)據(jù)校驗(yàn)與本地邏輯處理、發(fā)起ajax請求)、控制器(Controller,負(fù)責(zé)用戶和系統(tǒng)事件響應(yīng)、模型和渲染器調(diào)度)、渲染器(Renderer,對視圖的渲染,控制器與事件的綁定、數(shù)據(jù)搜集)的頁面開發(fā)新模式,并基于此模式提出了一個(gè)開發(fā)框架原型。

  關(guān)鍵字:

  MCRV設(shè)計(jì)模式 Javascript MVC Web開發(fā)標(biāo)準(zhǔn)

  1.Web前端開發(fā)面臨的問題

  早期的Web頁開發(fā)(Web前端開發(fā))中,Web頁面較為簡單,大多數(shù)Web頁面的功能僅限于用HTML和簡單樣式展示靜態(tài)信息,或向服務(wù)器發(fā)送數(shù)據(jù),Web頁面與用戶的交互較少。隨著Web的發(fā)展,DHTML、CSS、javascript等技術(shù)出現(xiàn),Web頁不再僅限于展示靜態(tài)信息,動(dòng)態(tài)、交互成為Web頁的主流功能之一。與此同時(shí),Web頁代碼規(guī)模也變的較大,頁面中的HTML、CSS、Javascript等代碼往往混雜在一起,如何很好的組織這些代碼,使Web客戶端程序具有很好的結(jié)構(gòu),易于閱讀和維護(hù),成為Web前端開發(fā)人員面臨的一個(gè)難題。在實(shí)踐中,業(yè)界提出了內(nèi)容(Content)-結(jié)構(gòu)(Structure)-表現(xiàn)(Presentation)-行為(Behavior)相分離的Web頁開發(fā)標(biāo)準(zhǔn)。在這種標(biāo)準(zhǔn)中,一個(gè)Web頁代碼可以分為如下四個(gè)部分: 內(nèi)容:頁面實(shí)際要傳達(dá)的真正信息,包含數(shù)據(jù)、文檔或者圖片等。

  結(jié)構(gòu):對內(nèi)容的劃分,使內(nèi)容更加具有邏輯性,易用性。類似頁面的標(biāo)題、作者、章、節(jié)、段落和列表。

  表現(xiàn):用來描述內(nèi)容外觀,稱之為“表現(xiàn)”,主要指CSS樣式。

  行為:行為就是對內(nèi)容的交互及操作效果。行為控制主要通過javascript實(shí)現(xiàn)。

  內(nèi)容-結(jié)構(gòu)-表現(xiàn)-行為(CSPB)開發(fā)標(biāo)準(zhǔn)對Web頁包含的的代碼進(jìn)行了分類,使代碼各個(gè)部分得到很好的分離,使Web頁初步具有了良好的結(jié)構(gòu)。隨后,Web進(jìn)入了嶄新的Web2.0時(shí)代,以Gmail為代表的Web2.0應(yīng)用大量出現(xiàn),并且取得很大的成功。這類Web頁的典型特征是用一個(gè)基于ajax技術(shù)的無刷新的頁面完成大量復(fù)雜的功能。此類頁面包括Web IM、Web Map、Gmail等應(yīng)用,統(tǒng)稱為one-page Web應(yīng)用。同時(shí),在企業(yè)級Web開發(fā)中,一個(gè)Web頁同時(shí)完成多個(gè)復(fù)雜功能的情況也越來越多。在這些復(fù)雜Web頁應(yīng)用中, Javascript代碼是此類富客戶端應(yīng)用程序的核心,負(fù)責(zé)與用戶的復(fù)雜交互和頁面展現(xiàn)。One-page Web頁面javascript代碼規(guī)模往往非常龐大,邏輯復(fù)雜,動(dòng)則千行以上,有時(shí)甚至需要一個(gè)團(tuán)隊(duì)來完成一個(gè)頁面的開發(fā)。如何合理組織大量的javascript代碼,使之具有良好的擴(kuò)展性,能夠適應(yīng)需求的變化,使代碼易于維護(hù),是廣大Web前端開發(fā)人員面臨的一大挑戰(zhàn)??v觀Web應(yīng)用程序開發(fā)的歷史,Web后端開發(fā)(PHP、J2EE、ASP.NET)與Web客戶端開發(fā)的發(fā)展過程有一定的相似性,曾面臨類似的問題。最初,Web程序功能簡單,代碼較少時(shí),所有的控制、邏輯、UI展現(xiàn)代碼混雜在一起;隨著Web發(fā)展,程序規(guī)模變大,按原有方式開發(fā)出的程序顯然不具有良好的結(jié)構(gòu),不利于大規(guī)模開發(fā)和后期維護(hù),也不利于Web開發(fā)人員工作和角色的進(jìn)一步細(xì)分,代碼復(fù)用性差,瓶頸開始出現(xiàn)。Web后端程序設(shè)計(jì)者的解決方法是進(jìn)行代碼分類,將控制代碼與展現(xiàn)代碼開始分離, 于是Web后端開發(fā)從所謂的Model1發(fā)展到Model2;同時(shí),傳統(tǒng)桌面程序設(shè)計(jì)中的MVC(模型-視圖-控制器)設(shè)計(jì)模式被引入,負(fù)責(zé)程序數(shù)據(jù)與邏輯計(jì)算的部分進(jìn)一步分離出來,形成了Web后端開發(fā)中的MVC開發(fā)模式。MVC設(shè)計(jì)模式貫穿了軟件工程分而治之的思想,有效解決了Web后端程序設(shè)計(jì)中的代碼組織和復(fù)用問題。采用同一設(shè)計(jì)模式(MVC)也使代碼更容易被他人理解,保證代碼可靠性;它使Web開發(fā)工作可以細(xì)分為業(yè)務(wù)邏輯開發(fā)和UI展現(xiàn)開發(fā)。因此,MVC也利于團(tuán)隊(duì)開發(fā)。那么,MVC設(shè)計(jì)思想是否也能應(yīng)用在前端開發(fā)中解決相關(guān)問題呢?既然問題具有許多相似性,筆者沿著相同的解決思路來試圖解決前端開發(fā)中的代碼組織問題。

  2.MVC設(shè)計(jì)模式

  在提出本文提出的MCRV設(shè)計(jì)模式之前,有必要對其所基于的MVC設(shè)計(jì)模式進(jìn)行闡述。MVC這個(gè)概念很早之前就被人提起[1],它代表一種設(shè)計(jì)思想。MVC是Model-View-Conroller的縮寫,即模型-視圖-控制器。這種開發(fā)模式將一個(gè)應(yīng)用程序分為三個(gè)部分,模型(model)實(shí)現(xiàn)商業(yè)邏輯,提供數(shù)據(jù);視圖(view)負(fù)責(zé)向用戶呈現(xiàn)界面和接受用戶交互;控制器(controller)則負(fù)責(zé)響應(yīng)用戶交互請求,對用戶請求進(jìn)行翻譯,根據(jù)不同的請求調(diào)用模型,執(zhí)行商業(yè)邏輯。控制器本質(zhì)上是一個(gè)調(diào)度器 (dispatcher),通過其包含的各個(gè)方法(action)來執(zhí)行具體的商業(yè)邏輯。MVC各個(gè)部件以最小的耦合性協(xié)同工作,從而使程序具有良好的可擴(kuò)展性和可維護(hù)性和復(fù)用性。MVC設(shè)計(jì)模式最開始被用于桌面程序設(shè)計(jì),典型地用于相同的數(shù)據(jù)需要不同的用戶交互界面的設(shè)計(jì)場景。在經(jīng)典的MVC設(shè)計(jì)思想中,控制器負(fù)責(zé)響應(yīng)用戶事件,根據(jù)事件類型和參數(shù)調(diào)用模型或改變視圖。每個(gè)模型對應(yīng)一個(gè)或者多個(gè)視圖,當(dāng)模型被控制器調(diào)用而得到改變時(shí),模型向所有向其注冊過的視圖發(fā)送通知,視圖根據(jù)從模型的中得到的信息改變外觀。這種設(shè)計(jì)模式可以用圖1表示。可以看出經(jīng)典MVC設(shè)計(jì)模式中Controller、Model 都可以改變視圖。

經(jīng)典MVC
圖1 經(jīng)典MVC基于MVC模式的Web開發(fā)(后端)一般可以用圖2表示。在這種模式下,controller負(fù)責(zé)解析用戶瀏覽器請求的URL,根據(jù)URL自動(dòng)調(diào)用controller中的不同的Action響應(yīng)用戶請求。Action調(diào)用model,然后將model返回的數(shù)據(jù)填充到view中,view被返回給用戶瀏覽器。Web服務(wù)端開發(fā)中典型的采用MVC模式的框架有CakePHP、Structs、Spring等等。
Server端Web開發(fā)中的MVC
圖2 Server端Web開發(fā)中的MVC相對于早期的經(jīng)典MVC模式,Web開發(fā)中的MVC模式存在一些變化,因?yàn)閷τ谝粋€(gè)桌面應(yīng)用程序而言,可以很方便地將視圖注冊給模型,當(dāng)模型數(shù)據(jù)發(fā)生改變時(shí),即時(shí)通知視圖頁面發(fā)生改變;而對于Web應(yīng)用而言,即使將多個(gè)頁面注冊給一個(gè)模型,當(dāng)模型發(fā)生變化時(shí),模型無法主動(dòng)發(fā)送消息給Web頁面(因?yàn)閃eb應(yīng)用都是基于請求/響應(yīng)模式的),只有當(dāng)用戶請求瀏覽該頁面時(shí),控制器才負(fù)責(zé)調(diào)用模型數(shù)據(jù)來更新Web頁面。同時(shí),Web開發(fā)中的MVC也比經(jīng)典MVC具有更小的耦合性,因?yàn)镸odel不再與View發(fā)生交互,因此程序的結(jié)構(gòu)更加良好,使Web前端開發(fā)和業(yè)務(wù)邏輯開發(fā)相分離變的簡單。對于具有復(fù)雜交互邏輯和豐富界面的程序來說,MVC已被實(shí)踐證明是一種行之有效的設(shè)計(jì)和開發(fā)思想。采用MVC設(shè)計(jì)模式的系統(tǒng)具有較好的結(jié)構(gòu),較低的耦合性,代碼具有很好的維護(hù)性,能夠適應(yīng)復(fù)雜的業(yè)務(wù)邏輯和視圖展現(xiàn)變化。它也非常適合團(tuán)隊(duì)開發(fā),使開發(fā)人員分為不同的角色,專注于自己負(fù)責(zé)部分的開發(fā)。

  3.MCRV設(shè)計(jì)模式

 

  綜上所述,MVC是解決具有復(fù)雜交互界面、代碼規(guī)模大的應(yīng)用程序面臨代碼組織、復(fù)用問題的有效設(shè)計(jì)模式。基于此,本文嘗試基于MVC設(shè)計(jì)思想解決前端開發(fā)中的類似問題。然而,在前端頁面開發(fā)中不能直接套用MVC設(shè)計(jì)模式。因?yàn)?,前端開發(fā)中的Web頁面包含了HTML、CSS、Javascript等多個(gè)種類的代碼,相對Web后端來說,Web頁面整體就是一個(gè)負(fù)責(zé)UI展現(xiàn)、用戶本地交互、發(fā)送服務(wù)請求的大View,與經(jīng)典MVC及Web后端開發(fā)MVC模式中的View皆有不同。因此,需要具體問題具體分析。首先對Web頁面中的HTML、CSS、Javascript等代碼進(jìn)一步分析,明確它們的具體功能分類。根據(jù)業(yè)界提出的Web開發(fā)標(biāo)準(zhǔn),Web頁首先被分為了內(nèi)容-結(jié)構(gòu)-表現(xiàn)-行為幾個(gè)部分。內(nèi)容、結(jié)構(gòu)、表現(xiàn)是頁面的靜態(tài)部分,主要負(fù)責(zé)UI的展現(xiàn),用戶操作指令(鍵盤、鼠標(biāo))的接受,因此,內(nèi)容、結(jié)構(gòu)、表現(xiàn)屬于視圖 (View)的范疇。行為主要就是javascript代碼,負(fù)責(zé)對用戶操作指令的響應(yīng)。在復(fù)雜ajax應(yīng)用中, javascript代碼的功能一般包括:響應(yīng)用戶指令,執(zhí)行數(shù)據(jù)驗(yàn)證/處理、執(zhí)行客戶端交互邏輯,向服務(wù)器發(fā)送ajax請求,接受并處理服務(wù)器返回的數(shù)據(jù),根據(jù)數(shù)據(jù)改變UI(向頁面結(jié)構(gòu)填充內(nèi)容數(shù)據(jù)、變換樣式等)。基于模型-視圖-控制器分離的思想,Javascript代碼中的數(shù)據(jù)驗(yàn)證/處理、本地業(yè)務(wù)邏輯計(jì)算、向服務(wù)器發(fā)請求獲取數(shù)據(jù)的功能,對應(yīng)模型(Model)的功能;響應(yīng)(翻譯)用戶操作指令,根據(jù)指令執(zhí)行業(yè)務(wù)邏輯處理的功能,屬于控制器(Controller)的功能;而接受處理過的數(shù)據(jù),根據(jù)數(shù)據(jù)修改頁面的內(nèi)容/結(jié)構(gòu)/樣式的功能既不屬于控制器的功范疇,也不屬于模型的功能范疇,這部分代碼因?yàn)楦鶕?jù)數(shù)據(jù)對View進(jìn)行呈現(xiàn)(render),可以命名為Renderer(渲染器或呈現(xiàn)器)。根據(jù)前述分析,本文提出了MCRV設(shè)計(jì)模式,如圖3所示。闡述如下: M(Model):模型。完成數(shù)據(jù)驗(yàn)證、數(shù)據(jù)處理,執(zhí)行客戶端業(yè)務(wù)邏輯計(jì)算,或向服務(wù)器發(fā)起ajax請求調(diào)用服務(wù)端邏輯、接受返回的數(shù)據(jù),將處理后的數(shù)據(jù)返回控制器。

  C(Controller):控制器??刂破黜憫?yīng)View上的事件,根據(jù)事件調(diào)度執(zhí)行模型的業(yè)務(wù)邏輯,從業(yè)務(wù)邏輯獲取返回?cái)?shù)據(jù),調(diào)度相應(yīng)的渲染器(Render)來完成界面展現(xiàn)。在這個(gè)過程中控制器會(huì)有數(shù)據(jù)的傳遞:控制器調(diào)用模型中的邏輯時(shí)會(huì)傳送Renderer搜集的數(shù)據(jù)(form表單各域的name/value、其他控制參數(shù)),模型執(zhí)行邏輯后返回作為執(zhí)行結(jié)果的數(shù)據(jù)給控制器,控制器根據(jù)數(shù)據(jù)來調(diào)用渲染器(renderer)來完成界面呈現(xiàn)(rendering),呈現(xiàn)(rendering)就是修改頁面結(jié)構(gòu)、內(nèi)容和樣式的過程。數(shù)據(jù)傳遞過程可以用圖4表示。

  R(Renderer):渲染器(呈現(xiàn)器)。渲染器被控制器調(diào)用,接受從控制器傳遞的數(shù)據(jù),完成對界面的具體渲染。渲染器也負(fù)責(zé)控件(widget)的初始化,及建立Controller與具體事件的對應(yīng)關(guān)系,事件發(fā)生時(shí)負(fù)責(zé)搜集View上的數(shù)據(jù)傳送到Controller。

  V(View):視圖。視圖是用戶最終看到的整個(gè)Web界面,由結(jié)構(gòu)、內(nèi)容、樣式(表現(xiàn))等靜態(tài)內(nèi)容共同構(gòu)成。View由Renderer進(jìn)行初始化渲染和修改。

  

MCRV開發(fā)模式

圖3:MCRV開發(fā)模式

 

  

數(shù)據(jù)傳遞過程

圖4:數(shù)據(jù)傳遞過程可以看到在MCRV開發(fā)模式中,Controller處于控制中心的位置,Model完成具體的商業(yè)邏輯計(jì)算以及向后端發(fā)起ajax請求返回?cái)?shù)據(jù)的功能。Controller與Model、Renderer之間的交互本質(zhì)上數(shù)據(jù)交互的過程,它們之間存在著一個(gè)數(shù)據(jù)流,如圖4所示。因此,制定Controller、Model、Renderer之間的交互接口時(shí),數(shù)據(jù)格式定義很重要。4.基于MCRV設(shè)計(jì)模式的Demo

 

  下面是一個(gè)用MCRV模式來開發(fā)的Demo頁面,頁面的功能是用表格展示和修改用戶信息。javascript使用了jQuery庫。頁面界面如圖5所示。頁面代碼在程序清單1中

基于MCRV設(shè)計(jì)模式的用戶管理Demo
圖5:基于MCRV設(shè)計(jì)模式的用戶管理Demo程序清單1

 

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www./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 設(shè)計(jì)模式 Demo</title> 
  7.         <style type="text/css"> 
  8.             /********表現(xiàn)*********/ 
  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.     <!-------結(jié)構(gòu)---------> 
  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.             //模擬的數(shù)據(jù),實(shí)際應(yīng)用中經(jīng)常從服務(wù)器獲取  
  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.             //獲得用戶數(shù)據(jù)列表 
  151.             this.getUserList=function() 
  152.             { 
  153.                 //todo ,可能ajax從后端返回 
  154.                 return this.data; 
  155.             }  
  156.  
  157.             //獲得用戶數(shù)據(jù) 
  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.             //修改用戶數(shù)據(jù) 
  166.             this.modifyUser=function(user) 
  167.             { 
  168.                 var result={success:true,msg:"修改成功"}; 
  169.                 //todo,驗(yàn)證參數(shù)user 
  170.                 //todo,修改用戶數(shù)據(jù) 
  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> 

  5.基于MCRV模式的開發(fā)框架原型

  5.1基本設(shè)計(jì)思想

  框架是在一個(gè)特定的問題領(lǐng)域內(nèi),應(yīng)用程序的部分設(shè)計(jì)與實(shí)現(xiàn)[2]。框架與設(shè)計(jì)模式通常是精密結(jié)合的。框架規(guī)定了應(yīng)用的體系結(jié)構(gòu),使基于特定設(shè)計(jì)模式的開發(fā)能夠復(fù)用公共代碼;反之,框架強(qiáng)調(diào)設(shè)計(jì)復(fù)用,框架設(shè)計(jì)也基本上使用了設(shè)計(jì)模式,掌握了框架的設(shè)計(jì)模式可以快速掌握基于框架的應(yīng)用程序開發(fā)。因此,使用MCRV設(shè)計(jì)模式進(jìn)行前端開發(fā)時(shí)最好有一個(gè)與之配合的javascript框架。

  基本設(shè)計(jì)考慮:? Model、Controller、Renderer組成一個(gè)三元組MCR,一個(gè)MCR三元組中Controller對象、Model對象和Renderer對象是唯一的。? Model、Controller、Renderer可以初始化和銷毀? Controller、Model、View在需要時(shí)可以透明地引用其他對象? 數(shù)據(jù)與邏輯分離,支持?jǐn)?shù)據(jù)本地存儲(chǔ)? 一個(gè)Web頁面可以有多個(gè)MCR組,即可以有多個(gè)Controller、Model、Renderer三元組分別完成不同的控制、邏輯、展現(xiàn)。這為一個(gè)頁面邏輯和交互非常復(fù)雜時(shí),拆分為多個(gè)模塊,由多人開發(fā)提供了支持。5.2 基本對象及其關(guān)系

  下面是一個(gè)基于上述考慮的基于MCRV設(shè)計(jì)模式的javascript框架原型(以下簡稱MCRV框架)。

  框架的基本對象:MCR、Model、Controller、Renderer、Cache。如圖6所示。

圖6 基于MCRV模式的框架原型
圖6 基于MCRV模式的框架原型? MCR:控制器(Controller)對象、模型對象(Model)和渲染器對象(Renderer)的復(fù)合對象。

 

  -Dispose()方法:執(zhí)行MCR銷毀操作,避免javascript內(nèi)存泄露;在頁面unload時(shí)自動(dòng)調(diào)用;這個(gè)方法自動(dòng)調(diào)用Model、Controller和Renderer的dispose()方法

  -model屬性:包含的模型

  -controller屬性:包含的控制器

  -renderer屬性:包含的渲染器? Model:模型對象。

  -init()方法:執(zhí)行模型初始化

  -dispose()方法:執(zhí)行對象銷毀,釋放資源

  -cahce屬性:數(shù)據(jù)的緩存。? Controller:控制器對象

  -init()方法:執(zhí)行控制器初始化

  -dispose()方法:執(zhí)行對象銷毀,釋放資源

  -model屬性:調(diào)度的模型

  -renderer屬性:控制的渲染器? Renderer:渲染器對象

  -init()方法:執(zhí)行渲染器初始化

  -dispose()方法:執(zhí)行對象銷毀,釋放資源

  -controller屬性:對controller的引用? Cache:基于key-value的緩存對象

  -get()方法:基于鍵值獲取緩存數(shù)據(jù)

  -set()方法:設(shè)置緩存數(shù)據(jù)

  -remove()方法:刪除對應(yīng)某個(gè)鍵值的緩存

  -size():緩存數(shù)量5.3 MCRV框架與其他web其他部分的關(guān)系

  基于MCRV模式的開發(fā)框架與Web頁面開發(fā)其他組成部分的關(guān)系可以用圖7表示。MCRV框架搭建起了js應(yīng)用程序整體的結(jié)構(gòu),提供了應(yīng)用程序上下文環(huán)境。MCRV框架可以與js組件庫、css基礎(chǔ)樣式庫和js業(yè)務(wù)邏輯組件一起作為應(yīng)用程序構(gòu)建的基礎(chǔ),并且它們之間沒有依賴關(guān)系。盡管應(yīng)用程序可以在js基礎(chǔ)庫(如jQuery)上開發(fā),但是MCRV框架不依賴這些庫。

圖7 基于MCRV模式的開發(fā)框架與其他Web頁其他部分的關(guān)系
圖7 基于MCRV模式的開發(fā)框架與其他Web頁其他部分的關(guān)系

  6.結(jié)論

 

  實(shí)踐表明,MCRV設(shè)計(jì)模式能夠有效解決復(fù)雜ajax開發(fā)中面臨的問題,可以使Web頁面代碼結(jié)構(gòu)良好,降低javascript代碼的耦合性,提高復(fù)用性、適應(yīng)性和靈活性,使Web頁更加易于維護(hù)和重構(gòu)。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    激情内射亚洲一区二区三区| 亚洲精品国产精品日韩| 在线欧洲免费无线码二区免费| 欧美又大又黄刺激视频| 国产又大又黄又粗的黄色| 99亚洲综合精品成人网色播| 亚洲专区中文字幕视频| 欧美有码黄片免费在线视频| 中日韩美女黄色一级片 | 国产精品乱子伦一区二区三区| 久久永久免费一区二区| 国产精品日韩精品最新| 91亚洲精品亚洲国产| 亚洲一区二区精品免费| 亚洲精品欧美精品一区三区| 丝袜破了有美女肉体免费观看| 久久精品一区二区少妇| 国产精品午夜福利在线观看| 大香蕉大香蕉手机在线视频| 日本女优一色一伦一区二区三区| 日韩免费成人福利在线| 在线观看那种视频你懂的| 嫩草国产福利视频一区二区| 国产熟女一区二区不卡| 亚洲国产精品久久琪琪| 国产爆操白丝美女在线观看| 日韩成人免费性生活视频| 国内胖女人做爰视频有没有| 国产成人精品国内自产拍| 99在线视频精品免费播放| 色哟哟精品一区二区三区| 正在播放玩弄漂亮少妇高潮| 国产毛片不卡视频在线| 国产亚洲欧美一区二区| 日韩特级黄片免费在线观看| 精品伊人久久大香线蕉综合| 欧美日韩精品久久亚洲区熟妇人| 国产在线一区二区免费| 暴力性生活在线免费视频| 日韩精品毛片视频免费看| 亚洲av又爽又色又色|