MVC是一种设计模式,独立于任何一门语言.
它将应用划分为3个部分:数据(模型),展示层(视图)和用户交互层(控制器)
一个事件的发生是这样的过程:
- 用户和应用产生交互.
- 控制器的事件处理器被触发
- 控制器从模型中请求数据,并将其交给视图.
- 视图将数据呈现给用户
模型
模型用来存放应用的所用数据对象。比如,可能有一个User模型,用以存放用户列表,他们的属性及所有与模型有关的逻辑.
模型不必知晓视图和控制器的细节,模型只需要包含数据及直接和这些数据
相关的逻辑. 任何事件处理代码,视图模板,以及那些和模型无关的逻辑都应当隔离在模型之外.将模型和视图的代码混在一起,是违反MVC架构原则的.模型是最应该从你的应用中解耦出来的部分.
当控制器从服务器抓取数据或创建新的记录时,他将数据包装成模型实例.
我们的数据是面向对象的,任何定义在这个数据模型上的函数或逻辑都可以直接被调用
,因此,不要这样做:
var user =users[“foo”];
destoryUser(user);
而要这样做:
var user =User.find(“foo”);
user.destory();
视图
视图层是呈现给用户的,用户与之产生交互.在JavaScript应用中,视图大都是由HTML,CSS和JavaScript模板组成的.视图不应当包含任何其他逻辑.
控制器
控制器是模型和视图之间的纽带.控制器从视图获得事件和输入,对他们
进行处理,并相应地更新视图.当页面加载时,控制器会给视图添加事件监听,比如监听表单提交或按钮.然后,当用户和你的应用产生交互时,控制器中的事件触发器就开始工作了.
不用类库和框架也能实现控制器,下面这个例子就是使用简单的jQuery代码来实现的:
var Controller={};
//使用匿名函数来封装一个作用域
(Controller.users=function($){
var nameClick=function(){/*...*/};
//在页面加载时绑定事件监听
$(function(){$("#view .name").click(nameClick)});
})(jQuery);
向模块化进军,创建类
var Class=function(){
var klass=function(){
this.init.apply(this,arguments);
};
klass.prototype.init=function(){};
return klass;
};
var Person = new Class;
Person.prototype.init=function(){
};
var person = new Person;
给类添加函数
Person.find=function(id){/*..*/};//静态函数
Person.prototype.breath = function(){/*...*/};//书上说是实例函数,但是我认为是基于原型链继承的函数,对象实例共享的方法
,如果实例对象的属性名与继承的属性名相同,继承的属性将被覆盖(overhide),除非显示调用继承的属性
一种常用的模式是给类的prototype起一个别名fn,写起来方便;
Person.fn=Person.prototype;
Person.fn.run=function(){};
给’类’库添加方法
现在,我们的"类"库(class library)包含了生成一个实例并初始化这个实例的功能,给类添加属性和给构造函数添加属性是一样的.
var Class=function(){
var klass=function(){
this.init.apply(this,arguments);
}
klass.prototype.init=function(name,age){this.name=name;this.age=age;};
//定义prototype的别名
klass.fn = klass.prototype;
//定义类的别名
klass.fn.parent=klass;
//给类添加属性
klass.extend=function(obj){
for(var i in obj){
if(!obj.hasOwnProperty(i))continue;
klass[i] =obj[i];
}
var extended=obj.extended;
if(extended) extended(klass);
};
//给实例添加属性
klass.include=function(obj){
var included=obj.included;
for(var i in obj){
if(!obj.hasOwnProperty(i))continue;
klass.fn[i] =obj[i];
}
if(included) included(klass);
};
return klass;
};
var ORMModule={
//共享函数
save:function(){}
};
var Person=new Class;
var Asset = new Class;
Person.include(ORMModule);
var asset = new Asset;
var person = new Person;
console.log(typeof asset.save);//"undefined"
console.log(typeof person.save);//"function"