原文: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) - 处理和响应事件,通常是用户操作,并监控模型上的变化,然后去修改视图。

The data of the component is a list of items, in which one particular item can be selected and deleted. So, the model of the component is very simple - it is stored in an array property and selected item property; and here it is:

我们将基于 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>

转载于:https://www.cnblogs.com/justjavac/archive/2013/01/08/model-view-controller-mvc-javascript.html

「译」JavaScript 的 MVC 模式相关推荐

  1. 变量、中文-「译」javascript 的 12 个怪癖(quirks)-by小雨

    在写这篇文章之前,xxx已经写过了几篇关于改变量.中文-主题的文章,想要懂得的朋友可以去翻一下之前的文章 原文:12 JavaScript quirks 译文:「译」javascript 的 12 个 ...

  2. 「译」javascript 中的 delete

    在这篇文章中作者从<JavaScript面向对象编程指南>一书中关于 delete 的错误讲起,详细讲述了关于 delete 操作的实现, 局限以及在不同浏览器和插件(这里指 firebu ...

  3. js最小化浏览器_「译」解析、抽象语法树(ast) +如何最小化解析时间的5个技巧...

    前言 该系列课程会在本周陆续更新完毕,主要讲解的都是工作中可能会遇到的真实开发中比较重要的问题以及相应的解决方法.通过本系列的课程学习,希望能对你日常的工作带来些许变化.当然,欢迎大家关注我,我将持续 ...

  4. 「译」一起探讨 JavaScript 的对象

    「译」一起探讨 JavaScript 的对象 原文地址:Let's explore objects in JavaScript 原文作者:Cristi Salcescu 译文出自:阿里云翻译小组 译文 ...

  5. iOS 9,为前端世界都带来了些什么?「译」

    2015 年 9 月,Apple 重磅发布了全新的 iPhone 6s/6s Plus.iPad Pro 与全新的操作系统 watchOS 2 与 tvOS 9(是的,这货居然是第 9 版),加上已经 ...

  6. jvm 系列(九):如何优化 Java GC 「译」

    本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. Sangmin Lee发表在Cubrid上的"Become a Java GC Expert ...

  7. jvm系列(十):如何优化Java GC「译」

    本文由CrowHawk翻译,地址:如何优化Java GC「译」,是Java GC调优的经典佳作. Sangmin Lee发表在Cubrid上的"Become a Java GC Expert ...

  8. 「译」一个3D网页是如何制作的

    「译」一个3D网页是如何制作的 原文: 本文作者制作了一个3D网页作为自己的个人主页,是一个遥控汽车的游戏页面.页面十分有趣,感兴趣的朋友可以先打开体验一下. 以下为原文的译文,是我个人理解的版本.大 ...

  9. 「译」如何正确学习JavaScript

    原文地址: http://www.crimx.com/2014/05/15/how-to-learn-javascript-properly 原文:How to Learn JavaScript Pr ...

最新文章

  1. numpy之argmax()函数
  2. ssh无法登录,提示Connection closing...Socket close.
  3. 使用wamp访问localhost时查看项目地址不对
  4. Enhanced LSTM for Natural Language Inference-学习笔记
  5. Kinect开发笔记之四检测并调试Kinect设备
  6. KNN 算法--图像分类算法
  7. Angular之ngx-permissions的常见使用情况
  8. 题目SPOOLing系统的设计与实现
  9. spring mvc 解决中文response乱码
  10. python制作小游戏大全_python制作小游戏(一)
  11. 2019年PMP考试模拟题(附答案解析)
  12. 知识产权助力中国经济高质量发展广受认可
  13. 整理备忘:【已解决】VMware虚拟机提示“锁定文件失败 打不开磁盘”
  14. 【IIS】XP系统的IIS发布
  15. ble学习笔记九----------ble协议栈之OSAL的运行机理
  16. 我的世界服务器修改器1.7.10,我的世界修改器_我的世界TMI内置修改器1.7.10 - 99单机游戏...
  17. Word Averaging模型做文本分类 稳定效果好模型简单
  18. win10输入法频繁自动中英文切换的问题
  19. 到底什么才是真正的商业智能(BI)
  20. Hash索引和BTree索引区别

热门文章

  1. mysql 把一列转多行_Oralce 按分隔符把一列转成多行
  2. idea新建module路径问题
  3. Tomcat如何配置X-Frame-Options头
  4. javascript不定参数
  5. 【PTA】 PAT乙级真题,95题(C++,AC代码)
  6. java 键盘输入密码,(JAVA)从键盘输入一批字符,以@结束,按要求加密并输出
  7. oracle declare语法_基于oracle数据库存储过程的创建及调用
  8. 接口 同花顺_Fiddler模拟接口数据(mock)
  9. Python入门--集合的创建,set(),{}
  10. wps 甘特图_【WPS神技能】在Excel表格中用图表阶梯式的展示任务进程?找甘特图呀...