web前端數據與變現分離之MVCR框架初體驗
爲什麼最近冒出這個研究方向,是因爲自己最近用做了個webAPP,這個項目中運用大量JS實現了頁面渲染與加載,以前寫JS也就幾行代碼, 這次規模超出了以前做web項目的大小,代碼從組織上顯現極大臃腫,儘管我採用面對對象方式,抽象很多功能,但是還是不能讓代碼變得好看點。 後來我去幾家公司,都問過我對數據與表現分離有麼有概念,我也茫然(在小公司的悲哀,井底之蛙,天只有井口大小),回來搜索資料學習之。
什麼是前端數據與表現分離?
在我寫的很多前端代碼中,如果頁面將class,ID等元素更換後(也就是更換HTML後),我面臨一個很尷尬的問題,以前寫的JS代碼 無法用了,如果要修改,修改點散落在前端中各個角落,想要重用代碼,幾乎是不可能的事情。特別是運用大量AJax的前端上面, 究其原因主要存在一下幾個部分:
1.對頁面元素的class id等元素選擇器分散在代碼各個地方,沒有抽象出來。
2.對於ajax異步獲取的數據,也沒有對數據持久層分離,基本都是按功能分散在代碼中各個部分。
3.經常在html中鑲嵌大量JS運用代碼而且是JS主要功能代碼,使代碼分散不宜維護。
web發展經歷幾個階段,從最開始的只是html展示到後來的CSS,js等技術的出現,漸漸的出現Content(內容)-structure(結構)-Presentation(表現) Behavior(動作)相分離的WEB開發標準,這是業界對前端規範,但是後來由於ajax大量運用,對前端代碼組織提出了新的挑戰。 在JS當中用後端MVC框架仿製的MVCR出現了。下面是我在使用後的一些經驗總結
首先是目錄結構的變換
我將JS代碼按照MVCR的代碼的方式分爲了model,controller,renderer和plugin,model文件夾中,主要放置的是ajax獲取數據或是 faye後臺主動推送的數據層。其主要方法代碼有
//實時刷新升級按鈕數據模型 function BunttonModel(){ this.init = function(){ } this.getBunttonList =function (fn){ var fayeClient = new FayeClient(); fayeClient.getResponse(fn); } }
而這裏沒用的fayeclinet對象是我放置於plugin文件下的代碼如下
//faye客戶端對象 function FayeClient() { try { var client = new Faye.Client("<%= "http://#{SystemInfo.new.get_ip}:9292/faye" %>") //這裏是運用了rails模塊代碼 this.client = client } catch (err) { console.log(err) } } FayeClient.prototype = { constructor: FayeClient, getResponse: function (fn) { this.client.subscribe("/message", function (response) { fn(response); }) } }
其實仔細的發現,我這裏製作做了反射調用,因爲以前已經寫了很多代碼了,我決定只是在model中封裝下fayeclient便行,下面 我們再看看renderer部分代碼。
//實時刷新按鈕渲染對象 function ButtonRenderer() { this.init = function () { } this.renderBunttonList = function (json) { var obj = new Walker(json) obj.list_each(); } }
好吧這裏walker也是我以前封裝的對象,我就不再顯示,下面我們再看看我們的controller部分
function BunttonController(){ this.init =function(){ this.model.getBunttonList(this.refreshBuntton()) } this.refreshBuntton= function(){ return this.renderer.renderBunttonList } }
各位看官看了,是不是覺得這些代碼運行起來肯定會報錯,controller怎麼去調用model,和renderer呢?我們這裏要請出我們起膠水作用的第三個類 MCR類
//MCR複合對象 function MCR(Controller,Model,Renderer){ this.controller = new Controller() this.model = new Model() this.renderer = new Renderer() this.controller.model = this.model this.controller.renderer = this.renderer this.model.controller = this.controller this.renderer.controller = this.controller if (typeof this.controller.init == "function"){ this.controller.init(); } if (typeof this.model.init == "function"){ this.model.init(); } if (typeof this.renderer.init == "function"){ this.renderer.init(); } }
上面的這個類將我們需要鏈接的controller,model,renderer,放置其中便可,而這樣的操作,我一般就放在需要調用這個功能的HTML頁面中如
<script type="text/javascript"> $(document).ready(function () { MCR(BunttonController,BunttonModel,ButtonRenderer) }) </script>
下面我們再用個UML圖表示下我們結構
總結
我在使用了MVCR框架組織JS代碼覺得他有這麼幾個特點
1.分離了JS代碼中數據(model),渲染(renderer),動作(controller),使代碼更加易懂,代碼組織結構更加合理。
2.減少了我在html鑲嵌JS代碼,使內容與動作相對更加獨立分離。
3.降低了代碼中的耦合度,提高了聚合程度。
相關內容同步到我的github blog 地址如下
http://jacksongblack.github.io/2014/05/24/%E5%89%8D%E7%AB%AF%E6%95%B0%E6%8D%AE%E4%B8%8E%E8%A1%A8%E7%8E%B0%E5%88%86%E7%A6%BB%E4%B9%8BMVCR%E6%A1%86%E6%9E%B6%E5%88%9D%E4%BD%93%E9%AA%8C.html