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出现了。下面是我在使用后的一些经验总结 

首先是目录结构的变换

web前端数据与变现分离之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图表示下我们结构

web前端数据与变现分离之MVCR框架初体验_前端框架 _02

总结

我在使用了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