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