Front

初学前端的MVC架构

Web应用的功能越来越强,Javascript代码也越来越多,大量的JS代码要以何种架构来组织就成了一个亟待解决的问题。老牌软件架构模式MVC(Model-View-Controller)就是一种相当不错的方案,虽然它定义不明确需要很多时间来思考如何组织,崇尚代码分离增加了调试难度,但毕竟脸熟(……),从用CakePHP的时候就接触过这个概念,以我能理解的方式描述就是:Models用来处理数据,View将处理结果呈现给用户,Controller用来连接这两者。所以一个Web应用的流程通常是这样的:

  • 1. 用户在View上进行操作——比如在文本框输入数值或是点击按钮
  • 2. Controller处理这个动作
  • 3. Controller通过Model对数据进行增删改查,将其传递到View
  • 4. View将数据展示给用户

以上描述来自Javascript Web Applications一书,其中有用MVC组织JS代码的具体方法。如果想偷懒的话,也有一些现成的JS框架来做这件事。说到JS框架可能最先想到的是jQuery,这类MVC框架和jQuery解决的问题不同,jQuery主要用来对页面元素进行操作上,比如我要移动一个按钮,或是将某个按钮设置为隐藏。而前端MVC框架除了将代码合理的组织以外,操作上也不是侧重于设置一个动作,当触发时进行某些处理这种方式。而是绑定Model,当Model改变时,View接收到通知,重新渲染。不需要手动指定页面元素更新HTML,改变Model时直接改变View。

Backbone

因为豆瓣说用的是Backbone,加上有37signal的背景,这个框架在国内颇有知名度,最先接触到的就是它了。Backbone的MVC是Models, Views, Collections。Models用于绑定键值数据和自定义事件;Collections提供API;Views声明事件处理函数,并通过RESRful JSON接口连接到应用程序。

Backbone将代码组织得很清晰,都扩展自它的MVC结构,例如:


Photo = Backbone.Model.extend({
    defaults: {
        src: 'placeholder.jpg',
        title: 'an image placeholder',
        coordinates: [0,0]
    },
    initialize: function(){
        this.bind("change:src", function(){
            var src = this.get("src"); 
            console.log('Image source updated to ' + src);
        });
    },
    changeSrc: function( source ){
        this.set({ src: source });
    }
});

var somePhoto = new Photo({ src: "test.jpg", title:"testing"});

var PhotoSearch = Backbone.View.extend({
    el: $('#results'),
    render: function( event ){
        var compiled_template = _.template( $("#results-template").html() );
        this.el.html( compiled_template(this.model.toJSON()) );
        return this; //recommended as this enables calls to be chained.
    },
    events: {
        "submit #searchForm":  "search",
        "click .reset": "reset",
        "click .advanced": "switchContext"
    },
    search: function( event ){
        //executed when a form '#searchForm' has been submitted
    },
    reset: function( event ){
        //executed when an element with class "reset" has been clicked.
    },
    //etc
});

PhotoCollection = Backbone.Collection.extend({
    model: Photo
});

Backbone官方提供了很多例子,但没有具体的教程,我最后是看了这篇教程才弄懂了大致的写法,上面的代码也主要来自这篇教程。

KnockoutJS

KnockoutJS简称KO,这个框架的教程做得非常好,所以学起来比Backbone容易很多。

KO是以MVVM(Model-View-View Model)的形式来组织代码的,比较有趣的是它的绑定方式,不是先获得元素再使用bind,而是直接把bind写在属性里,例如:


<p>Item name: <strong data-bind="text: itemName"></strong></p>

var cartViewModel = {
    itemName: '${name}', //从nodejs+jqtpl的后台取得数据
};
    
ko.applyBindings(cartViewModel);

比如要把Model-View里的数据,传递到View中,当改变时临时更改


<select data-bind="options: items ,optionsCaption: 'Choose...',
optionsText: 'name',value: chosenItem"></select>              
<p data-bind="with: chosenItem"><b data-bind="text:type"></b></p>

<script type="text/javascript">
    function itemViewModel() {
        this.items = [
            { name: "Dmyz", type: "website" },
            { name: "Perchouli", type: "people" },
        ];
        this.chosenItem = ko.observable();
    }
    ko.applyBindings(new itemViewModel());
</script>

Afterword

这两个框架我现在了解得都不够深,很多函数还没用到。Backbone对代码的组织很清晰,需要依赖jQuery和Underscore,学起来比较费劲。KO框架的教程远比Backbone详细,不依赖其他框架,只是每个标签里都得加个bind-data的属性还是挺麻烦的。总之先用空余时间做个实际的小项目,具体用哪个框架得看之后具体遇到的问题了。

0 0 投票数
文章评分
订阅评论
提醒
guest

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

2 评论
最新
最旧 最多投票
内联反馈
查看所有评论
trackback

[…] 11年刚开始用前端MVC框架时写过一篇文章,当时Knockout和Backbone都在用,但之后的项目全是在用Backbone,主要因为它足够轻足够灵活,无论是富JS应用还是企业网站都用得上。写这篇教程的动机,是最近有做在线教育的朋友谈到好的中文入门教程比较稀缺,于是我想针对自己用得最多的框架写一篇入门教程,说明如下: […]

沈振宇
12 年 前

有空可以试一下多说的管理后台
Backbone + underscore + handelbars + jQuery,前两天刚刚上线的。