`

「译」JavaScript 的 MVC 模式

阅读更多

原文:Model-View-Controller (MVC) with JavaScript

作者:Alex@Net

译文:JavaScript 的 MVC 模式

译者:justjavac

本文介绍了模型-视图-控制器模式在 JavaScript 中的实现。

我喜欢 JavaScript,因为它是在世界上最灵活的语言之一。 在 JavaScript 中,程序员可以根据自己的口味选择编程风格:面向过程或面向对象。 如果你是一个重口味,JavaScript 一样可以应付自如: 面向过程,面向对象,面向方面, 使用 JavaScript 开发人员甚至可以使用函数式编程技术

这篇文章中,我的目标是编写一个简单的 JavaScript 组件,来向大家展示一下 JavaScript 的强大。 该组件是一个可编辑的项目列表(HTML中的 select 标签):用户可以选择某一项并删除它,或者添加新的项目到列表中。 组件将由三个类构成,分别对应着 MVC 设计模式的模型-视图-控制器。

这篇文章只是一个简单的指导。 如果你希望在实际的项目中使用它,你需要进行适当的修改。 我相信你拥有创建和运行 JavaScript 程序的一切:大脑,双手,文本编辑器(如记事本),浏览器(例如我的最爱 Chrome)。

既然我们的代码要使用 MVC 模式,因此我在这里简单介绍一个这个设计模式。 MVC 模式的英文名称是 Model-View-Controller pattern,顾名思义,其主要部分组成:

  • 模型Model(),用于存储程序中使用到的数据;
  • 视图(View),用不同的表现形式来呈现数据;
  • 控制器(Controller),更新模型。

在维基百科对 MVC 体系结构的定义中,它由如下三部分组成:

模型(Model) -“数据模型”(Model)用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。 “模型”有对数据直接访问的权力。 “模型”不依赖“视图”和“控制器”,也就是说,模型不关心它会被如何显示或是如何被操作。

视图(View) - 视图层能够实现数据有目的的显示,通常是一个用户界面元素。 在视图中一般没有程序上的逻辑。 在 Web 应用程序中的 MVC,通常把显示动态数据的 html 页面称为视图。

控制器(Controller) - 处理和响应事件,通常是用户操作,并监控模型上的变化,然后去修改视图。

我们将基于 MVC 实现一个数据列表组件,列表中的项目可以被选择和删除。 因此,组件模型是非常简单的 - 它只需要两个属性:

  1. 数组 _items 用来存储所有元素
  2. 普通变量 _selectedIndex 用来存储选定的元素索引

代码如下:

/**
 * 模型。
 *
 * 模型存储所有元素,并在状态变更时通知观察者(Observer)。
 */ 
function ListModel(items) {
    this._items = items;        // 所有元素
    this._selectedIndex = -1;   // 被选择元素的索引

    this.itemAdded = new Event(this);
    this.itemRemoved = new Event(this);
    this.selectedIndexChanged = new Event(this);
}

ListModel.prototype = {
    getItems : function () {
        return [].concat(this._items);
    },

    addItem : function (item) {
        this._items.push(item);
        this.itemAdded.notify({item : item});
    },

    removeItemAt : function (index) {
        var item;

        item = this._items[index];
        this._items.splice(index, 1);
        this.itemRemoved.notify({item : item});

        if (index === this._selectedIndex) {
            this.setSelectedIndex(-1);
        }
    },

    getSelectedIndex : function () {
        return this._selectedIndex;
    },

    setSelectedIndex : function (index) {
        var previousIndex;

        previousIndex = this._selectedIndex;
        this._selectedIndex = index;
        this.selectedIndexChanged.notify({previous : previousIndex});
    }
};

Event 是一个简单的实现了观察者模式(Observer pattern)的类:

function Event(sender) {
    this._sender = sender;
    this._listeners = [];
}

Event.prototype = {
    attach : function (listener) {
        this._listeners.push(listener);
    },

    notify : function (args) {
        var index;

        for (index = 0; index < this._listeners.length; index += 1) {
            this._listeners[index](this._sender, args);
        }
    }
};

View 类需要定义控制器类,以便与它交互。 虽然这个任务可以有许多不同的接口(interface),但我更喜欢最简单的。 我希望我的项目是在一个 ListBox 控件和它下面的两个按钮:“加号”按钮添加项目,“减”删除所选项目。 组件所提供的“选择”功能则需要 select 控件的原生功能的支持。

一个 View 类被绑定在一个 Controller 类上, 其中「…控制器处理用户输入事件,通常是通过一个已注册的回调函数」(wikipedia.org)。

下面是 View 和 Controller 类:

/**
 * 视图。
 * 
 * 视图显示模型数据,并触发 UI 事件。
 * 控制器用来处理这些用户交互事件
 */ 
function ListView(model, elements) {
    this._model = model;
    this._elements = elements;

    this.listModified = new Event(this);
    this.addButtonClicked = new Event(this);
    this.delButtonClicked = new Event(this);

    var _this = this;

    // 绑定模型监听器
    this._model.itemAdded.attach(function () {
        _this.rebuildList();
    });

    this._model.itemRemoved.attach(function () {
        _this.rebuildList();
    });

    // 将监听器绑定到 HTML 控件上
    this._elements.list.change(function (e) {
        _this.listModified.notify({ index : e.target.selectedIndex });
    });

    this._elements.addButton.click(function () {
        _this.addButtonClicked.notify();
    });

    this._elements.delButton.click(function () {
        _this.delButtonClicked.notify();
    });
}

ListView.prototype = {
    show : function () {
        this.rebuildList();
    },

    rebuildList : function () {
        var list, items, key;

        list = this._elements.list;
        list.html('');

        items = this._model.getItems();
        for (key in items) {
            if (items.hasOwnProperty(key)) {
                list.append($('<option>' + items[key] + '</option>'));
            }
        }

        this._model.setSelectedIndex(-1);
    }
};

/**
 * 控制器。
 *
 * 控制器响应用户操作,调用模型上的变化函数。
 */ 
function ListController(model, view) {
    this._model = model;
    this._view = view;

    var _this = this;

    this._view.listModified.attach(function (sender, args) {
        _this.updateSelected(args.index);
    });

    this._view.addButtonClicked.attach(function () {
        _this.addItem();
    });

    this._view.delButtonClicked.attach(function () {
        _this.delItem();
    });
}

ListController.prototype = {
    addItem : function () {
        var item = window.prompt('Add item:', '');
        if (item) {
            this._model.addItem(item);
        }
    },

    delItem : function () {
        var index;

        index = this._model.getSelectedIndex();
        if (index !== -1) {
            this._model.removeItemAt(this._model.getSelectedIndex());
        }
    },

    updateSelected : function (index) {
        this._model.setSelectedIndex(index);
    }
};

当然,ModelViewController 类应当被实例化。

下面是一个使用此 MVC 的完整代码:

$(function () {
    var model = new ListModel(['PHP', 'JavaScript']),

    view = new ListView(model, {
        'list' : $('#list'), 
        'addButton' : $('#plusBtn'), 
        'delButton' : $('#minusBtn')
    }),

    controller = new ListController(model, view);        
    view.show();
});

<select id="list" size="10" style="width: 15em"></select><br/>
<button id="plusBtn">  +  </button>
<button id="minusBtn">  -  </button>
18
19
分享到:
评论
4 楼 chenhaiyang 2013-01-14  
楼主想法真多啊。
3 楼 gxwudi008 2013-01-14  
只想说,写的真是一板一眼~
2 楼 丫子 2012-12-18  
学习。。。
1 楼 coffeescript 2012-12-18  
学习了。MVC无处不在。

相关推荐

    ASP.NET设计模式-杨明军译(源码)

    8.4.2 ASP.NET MVC框架 8.4.3 利用AutoMapper映射ViewModel 8.4.4 Castle MonoRail 8.5 Page Controller模式 8.6 小结 第9章 用户体验层 9.1 什么是AJAX 9.2 使用JavaScript库 9.3 理解AJAX模式 9.3.1 ...

    用XMLHttpRequest和struts实现AJAX(译)[转]

    3. **Struts框架**:Struts是一个基于MVC(Model-View-Controller)设计模式的Java Web开发框架。它帮助开发者组织和管理应用的业务逻辑、界面表示和控制流程,提供了处理HTTP请求、验证输入、转发请求到相应资源等...

    BBS论坛(C#)

    - ASP.NET MVC是一个用于构建动态网站的开源框架,它遵循模型-视图-控制器(MVC)设计模式,使得代码结构清晰,易于测试和维护。 - ASP.NET Core MVC是.NET Core平台上的MVC框架,跨平台且性能更高,提供了更现代...

    PHP100教程2012版:CodeIgniter框架教程(3)(第17讲) 解压密码

    - **设计思路**:同样采用MVC模式进行设计,其中Article模型用于处理文章相关的数据库操作;ArticleController控制器用于接收用户的请求并调用模型处理数据;View层用于展示文章列表及详情页。 - **技术栈**:PHP、...

    JSP学生学籍管理系统(源代码+论文+开题报告+答辩PPT+外文翻译)_jsp_java源程序代码.rar

    本系统采用了Model-View-Controller(MVC)设计模式,其中,Model代表数据模型,View负责显示数据,Controller处理用户请求并控制Model和View的交互。这种模式有利于软件的模块化,提高代码的可读性和可维护性。 六...

    西游BBS系统asp,net

    在系统架构上,西游BBS可能采用了MVC(Model-View-Controller)模式,这是一种设计模式,用于组织Web应用程序的代码结构。Model负责数据处理,View负责用户界面展示,Controller处理用户请求并协调Model和View之间的...

    bbs网站源代码

    - MVC模式:多数BBS源代码遵循Model-View-Controller(MVC)架构,模型负责业务逻辑,视图负责展示,控制器协调二者。这种模式有助于代码组织和维护。 - AJAX异步通信:为了提供更好的用户体验,源码可能会利用...

    jsp_bbs 论坛代码

    学习和理解这个"jsp_bbs"项目,开发者可以深入理解JSP和Java EE的Web开发,包括MVC模式的应用、数据库交互、用户认证与授权、权限管理、页面跳转、数据封装和持久化等关键知识点。同时,对于熟悉论坛功能的实现,如...

    asp.net bbs论坛源代码

    - MVC(Model-View-Controller)架构:这是一种设计模式,将业务逻辑、数据和用户界面分离,便于开发和维护。 - ADO.NET:用于数据库访问,处理用户数据和论坛内容。 - LINQ:语言集成查询,简化数据库查询语句。 - ...

    BBS论坛系统

    MVC则采用模型-视图-控制器设计模式,有利于代码组织和测试,更适合大型项目。 数据库通常选择SQL Server,用于存储用户信息、帖子数据等。ORM(对象关系映射)工具如Entity Framework可以帮助简化数据库操作。 ...

    Laravel开发-entitize

    Laravel是PHP中的一款流行、优雅的Web应用开发框架,它遵循MVC(模型-视图-控制器)架构模式,旨在提高开发效率,提供丰富的功能和强大的工具,如Eloquent ORM、Artisan命令行工具、Blade模板引擎等。 在Laravel中...

    留言板eclipse做的一个留言板

    学习者可以借此理解HTTP协议、MVC设计模式,以及服务器与客户端之间的交互。 3. **数据库管理**:留言板通常需要持久化存储用户信息和留言内容,因此会用到关系型数据库如MySQL或Oracle。这包括了SQL语言的学习,...

    BBS论坛小程序

    BBS论坛小程序通常采用MVC(Model-View-Controller)设计模式,将数据模型、视图展示和用户控制逻辑分离,提高代码的可维护性和可扩展性。在前端,利用HTML5、CSS3和JavaScript构建用户界面,结合微信小程序或支付宝...

    任务书_基于SSH的校园二手书交易系统word文档良心出品.docx

    - **Struts2**:是一个开源的Web应用框架,遵循MVC架构模式,提供了丰富的标签库和拦截器机制,使得开发者能够更轻松地创建复杂的Web应用程序。 - **Spring**:Spring框架的核心特性包括依赖注入(DI)、面向切面...

    angular-larenga:创建于StackBlitz:high_voltage:

    通常,Angular以其MVC(Model-View-Controller)架构模式和依赖注入机制为特点,帮助开发者构建动态和模块化的Web应用。 【标签解析】:“HTML”标签表明项目可能涉及了HTML(超文本标记语言)的使用,这是网页内容...

    do_it_django:심범수의

    1. **Django 框架**:Django 是一个免费开源的 Web 开发框架,由 Python 编写,遵循 MVC(Model-View-Controller)设计模式,但更准确地说是 MTV(Model-Template-View)架构。它提供了完整的数据库管理、表单处理、...

Global site tag (gtag.js) - Google Analytics