JavaScript 的 MVC 模式
2012-12-18 22:49
267 查看
原文:Model-View-Controller(MVC)withJavaScript
作者:Alex@Net
译文:JavaScript的MVC模式
译者:justjavac
本文介绍了模型-视图-控制器模式在JavaScript中的实现。
我喜欢JavaScript,因为它是在世界上最灵活的语言之一。在JavaScript中,程序员可以根据自己的口味选择编程风格:面向过程或面向对象。如果你是一个重口味,JavaScript一样可以应付自如:面向过程,面向对象,面向方面,
使用JavaScript开发人员甚至可以使用函数式编程技术。
这篇文章中,我的目标是编写一个简单的JavaScript组件,来向大家展示一下JavaScript的强大。该组件是一个可编辑的项目列表(HTML中的select标签):用户可以选择某一项并删除它,或者添加新的项目到列表中。组件将由三个类构成,分别对应着MVC
设计模式的模型-视图-控制器。
这篇文章只是一个简单的指导。如果你希望在实际的项目中使用它,你需要进行适当的修改。我相信你拥有创建和运行JavaScript程序的一切:大脑,双手,文本编辑器(如记事本),浏览器(例如我的最爱Chrome)。
既然我们的代码要使用MVC模式,因此我在这里简单介绍一个这个设计模式。MVC模式的英文名称是Model-View-Controllerpattern,顾名思义,其主要部分组成:
模型Model(),用于存储程序中使用到的数据;
视图(View),用不同的表现形式来呈现数据;
控制器(Controller),更新模型。
在维基百科对MVC体系结构的定义中,它由如下三部分组成:
模型(Model)-“数据模型”(Model)用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“模型”有对数据直接访问的权力。“模型”不依赖“视图”和“控制器”,也就是说,模型不关心它会被如何显示或是如何被操作。
视图(View)-视图层能够实现数据有目的的显示,通常是一个用户界面元素。在视图中一般没有程序上的逻辑。在Web应用程序中的MVC,通常把显示动态数据的html页面称为视图。
控制器(Controller)-处理和响应事件,通常是用户操作,并监控模型上的变化,然后去修改视图。
Thedataofthecomponentisalistofitems,inwhichoneparticularitemcanbeselectedanddeleted.So,themodelofthecomponentisverysimple-itisstoredinanarraypropertyandselecteditemproperty;andhereitis:
我们将基于MVC实现一个数据列表组件,列表中的项目可以被选择和删除。因此,组件模型是非常简单的-它只需要两个属性:
数组_items用来存储所有元素
普通变量_selectedIndex用来存储选定的元素索引
代码如下:
Event是一个简单的实现了观察者模式(Observerpattern)的类:
View类需要定义控制器类,以便与它交互。虽然这个任务可以有许多不同的接口(interface),但我更喜欢最简单的。我希望我的项目是在一个ListBox控件和它下面的两个按钮:“加号”按钮添加项目,“减”删除所选项目。组件所提供的“选择”功能则需要select控件的原生功能的支持。
一个View类被绑定在一个Controller类上,其中「…控制器处理用户输入事件,通常是通过一个已注册的回调函数」(wikipedia.org)。
下面是View和Controller类:
当然,Model,View,Controller类应当被实例化。
下面是一个使用此MVC的完整代码:
view
source
print?
作者:
译文:
译者:
本文介绍了
我喜欢JavaScript,因为它是在世界上最灵活的语言之一。在JavaScript中,程序员可以根据自己的口味选择编程风格:面向过程或面向对象。如果你是一个重口味,JavaScript一样可以应付自如:面向过程,面向对象,
使用JavaScript开发人员甚至可以使用
这篇文章中,我的目标是编写一个简单的JavaScript组件,来向大家展示一下JavaScript的强大。该组件是一个可编辑的项目列表(HTML中的select标签):用户可以选择某一项并删除它,或者添加新的项目到列表中。组件将由三个类构成,分别对应着MVC
设计模式的模型-视图-控制器。
这篇文章只是一个简单的指导。如果你希望在实际的项目中使用它,你需要进行适当的修改。我相信你拥有创建和运行JavaScript程序的一切:大脑,双手,文本编辑器(如记事本),浏览器(例如我的最爱Chrome)。
既然我们的代码要使用MVC模式,因此我在这里简单介绍一个这个设计模式。MVC模式的英文名称是Model-View-Controllerpattern,顾名思义,其主要部分组成:
模型Model(),用于存储程序中使用到的数据;
视图(View),用不同的表现形式来呈现数据;
控制器(Controller),更新模型。
在维基百科对MVC体系结构的定义中,它由如下三部分组成:
模型(Model)-“数据模型”(Model)用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“模型”有对数据直接访问的权力。“模型”不依赖“视图”和“控制器”,也就是说,模型不关心它会被如何显示或是如何被操作。
视图(View)-视图层能够实现数据有目的的显示,通常是一个用户界面元素。在视图中一般没有程序上的逻辑。在Web应用程序中的MVC,通常把显示动态数据的html页面称为视图。
控制器(Controller)-处理和响应事件,通常是用户操作,并监控模型上的变化,然后去修改视图。
Thedataofthecomponentisalistofitems,inwhichoneparticularitemcanbeselectedanddeleted.So,themodelofthecomponentisverysimple-itisstoredinanarraypropertyandselecteditemproperty;andhereitis:
我们将基于MVC实现一个数据列表组件,列表中的项目可以被选择和删除。因此,组件模型是非常简单的-它只需要两个属性:
数组_items用来存储所有元素
普通变量_selectedIndex用来存储选定的元素索引
代码如下:
01 | /** |
02 | * 模型。 |
03 | * |
04 | * 模型存储所有元素,并在状态变更时通知观察者(Observer)。 |
05 | */ |
06 | function ListModel(items) { |
07 | this ._items // 所有元素 |
08 | this ._selectedIndex // 被选择元素的索引 |
09 |
10 | this .itemAdded new Event( this ); |
11 | this .itemRemoved new Event( this ); |
12 | this .selectedIndexChanged new Event( this ); |
13 | } |
14 |
15 | ListModel.prototype |
16 | getItems function () { |
17 | return [].concat( this ._items); |
18 | }, |
19 |
20 | addItem function (item) { |
21 | this ._items.push(item); |
22 | this .itemAdded.notify({item |
23 | }, |
24 |
25 | removeItemAt function (index) { |
26 | var item; |
27 |
28 | item this ._items[index]; |
29 | this ._items.splice(index, 1); |
30 | this .itemRemoved.notify({item |
31 |
32 | if (index this ._selectedIndex) { |
33 | this .setSelectedIndex(-1); |
34 | } |
35 | }, |
36 |
37 | getSelectedIndex function () { |
38 | return this ._selectedIndex; |
39 | }, |
40 |
41 | setSelectedIndex function (index) { |
42 | var previousIndex; |
43 |
44 | previousIndex this ._selectedIndex; |
45 | this ._selectedIndex |
46 | this .selectedIndexChanged.notify({previous |
47 | } |
48 | }; |
01 | function Event(sender) { |
02 | this ._sender |
03 | this ._listeners |
04 | } |
05 |
06 | Event.prototype |
07 | attach function (listener) { |
08 | this ._listeners.push(listener); |
09 | }, |
10 |
11 | notify function (args) { |
12 | var index; |
13 |
14 | for (index this ._listeners.length; |
15 | this ._listeners[index]( this ._sender, args); |
16 | } |
17 | } |
18 | }; |
一个View类被绑定在一个Controller类上,其中「…控制器处理用户输入事件,通常是通过一个已注册的回调函数」(wikipedia.org)。
下面是View和Controller类:
001 | /** |
002 | * 视图。 |
003 | * |
004 | * |
005 | * 控制器用来处理这些用户交互事件 |
006 | */ |
007 | function ListView(model, |
008 | this ._model |
009 | this ._elements |
010 |
011 | this .listModified new Event( this ); |
012 | this .addButtonClicked new Event( this ); |
013 | this .delButtonClicked new Event( this ); |
014 |
015 | var _this this ; |
016 |
017 | // 绑定模型监听器 |
018 | this ._model.itemAdded.attach( function () { |
019 | _this.rebuildList(); |
020 | }); |
021 |
022 | this ._model.itemRemoved.attach( function () { |
023 | _this.rebuildList(); |
024 | }); |
025 |
026 | // |
027 | this ._elements.list.change( function (e) { |
028 | _this.listModified.notify({ |
029 | }); |
030 |
031 | this ._elements.addButton.click( function () { |
032 | _this.addButtonClicked.notify(); |
033 | }); |
034 |
035 | this ._elements.delButton.click( function () { |
036 | _this.delButtonClicked.notify(); |
037 | }); |
038 | } |
039 |
040 | ListView.prototype |
041 | show function () { |
042 | this .rebuildList(); |
043 | }, |
044 |
045 | rebuildList function () { |
046 | var list, |
047 |
048 | list this ._elements.list; |
049 | list.html( '' ); |
050 |
051 | items this ._model.getItems(); |
052 | for (key in items) { |
053 | if (items.hasOwnProperty(key)) { |
054 | list.append($( '<option>' + '</option>' )); |
055 | } |
056 | } |
057 |
058 | this ._model.setSelectedIndex(-1); |
059 | } |
060 | }; |
061 |
062 | /** |
063 | * 控制器。 |
064 | * |
065 | * 控制器响应用户操作,调用模型上的变化函数。 |
066 | */ |
067 | function ListController(model, |
068 | this ._model |
069 | this ._view |
070 |
071 | var _this this ; |
072 |
073 | this ._view.listModified.attach( function (sender, |
074 | _this.updateSelected(args.index); |
075 | }); |
076 |
077 | this ._view.addButtonClicked.attach( function () { |
078 | _this.addItem(); |
079 | }); |
080 |
081 | this ._view.delButtonClicked.attach( function () { |
082 | _this.delItem(); |
083 | }); |
084 | } |
085 |
086 | ListController.prototype |
087 | addItem function () { |
088 | var item 'Add item:' , '' ); |
089 | if (item) { |
090 | this ._model.addItem(item); |
091 | } |
092 | }, |
093 |
094 | delItem function () { |
095 | var index; |
096 |
097 | index this ._model.getSelectedIndex(); |
098 | if (index |
099 | this ._model.removeItemAt( this ._model.getSelectedIndex()); |
100 | } |
101 | }, |
102 |
103 | updateSelected function (index) { |
104 | this ._model.setSelectedIndex(index); |
105 | } |
106 | }; |
下面是一个使用此MVC的完整代码:
view
source
01 | $( function () { |
02 | var model new ListModel([ 'PHP' , 'JavaScript' ]), |
03 |
04 | view new ListView(model, { |
05 | 'list' : $( '#list' ), |
06 | 'addButton' : $( '#plusBtn' ), |
07 | 'delButton' : $( '#minusBtn' ) |
08 | }), |
09 |
10 | controller new ListController(model, |
11 | view.show(); |
12 | }); |
13 |
14 | <select id= "list" size= "10" style= "width: 15em" ></select><br/> |
15 | <button id= "plusBtn" > |
16 | <button id= "minusBtn" > |
相关文章推荐
- javascript 开发中的 MVC 模式分析
- JavaScript 的 MVC 模式
- 【转】稍微谈一下 javascript 开发中的 MVC 模式
- 使用 MVC 模式实现 JavaScript 树形结构
- 「译」JavaScript 的 MVC 模式
- 「译」JavaScript 的 MVC 模式
- 稍微谈一下 javascript 开发中的 MVC 模式
- 谈谈关于JavaScript 中的 MVC 模式
- JavaScript中的MVC,MVP和MVVM模式剖析
- JavaScript 的 MVC 模式
- 稍微谈一下 javascript 开发中的 MVC 模式
- 稍微谈一下 javascript 开发中的 MVC 模式
- JavaScript 的 MVC 模式
- JavaScript 的 MVC 模式
- WEB前端 -- JavaScript 的 MVC 模式
- 「译」JavaScript 的 MVC 模式
- MVC 模式在javascript中的应用
- 谈谈关于JavaScript 中的 MVC 模式
- JavaScript 的 MVC 模式
- 学习JavaScript设计模式(策略模式)