最近又把《基于MVC的Javascript web富应用开发》过了一遍....看着自己的年度规划还有好多事没做(哈,要好好把握进度啊),但是也不能留旧账啊,所以还是总结一下啦,该书
对MVC做了基础的介绍,如果想往框架和类库方面探究,可以看看。
一、MVC基础
1、模型
模型用来存放应用的数据对象;比如一个User模型; 模型不必知晓试图和控制器的细节; 模型最应该从应用中解藕; 当控制器从服务器抓取数据或创建新纪录时,可以将数据包装成模型实例;
例如: //good case //封装 & 实例方法 var user = new User('name', 'tel', 'job'); user.destroy(); //bad case //因为destoryUser不在User的实例中 var user = {name: 'vczero', tel: '132******', job: '前端'}; destoryUser(user);
2、视图
视图主要由html、CSS、js模板; 模板中不应该存在逻辑,除了条件语句之外;
例如: //render.js function render(data){ //something to do //... view('userinfo', data); } //tpl.html <div> <span>{{data.name}}</span> <span>{{data.age}}</span> </div>
3、控制器
控制器是视图间的纽带; 控制器会给视图添加事件监听;
例如: function userController(){ //.... } userController.add('#btn', 'click', function(){...});
二、构建类
1、构造函数:第一次实践
//通过new和构造函数 var User = function(name, nickname){ this.name = name; this.nickname = nickname; } //实例化对象 good case var user = new User('vczero', '鬼谣');
2、模拟类库
var Class = function(){ var klass = function(){ this.init.apply(this, arguments); }; klass.PRototype.init = function(){}; return klass; } var User = new Class(); //初始化 User.prototype.init = function(){ console.log('------hello world-------'); } //添加实例函数 User.prototype.show = function(){ console.log('show method'); } //添加静态函数 User.userCompare = function(){ console.log('这里当然可以使用this比较'); } var user = new User(); //为了简洁,可以给类的prototype起个别名 //例如User.fn = User.prototype; //User.fn.add = function(){....}
3、封装:更加清楚的表达
//上面的模拟类库表达不是很直观,因此采用新的方式 //增加extend和include方法 var Class = function(){ var klass = function(){ this.init.apply(this, arguments); }; klass.prototype.init = function(){}; //prototype别名 klass.fn = klass.prototype; //类别名 klass.fn.parent = klass; //增加类属性 Klass.extend = function(obj){ var extended = obj.extended; for(var i in obj){ klass[i] = obj[i]; } if(extended)extended(klass); }; //增加实例属性 klass.include = function(obj){ var included = obj.included; for(var i in obj){ klass.fn[i] = obj[i]; } if(included) included(klass); }; return klass; } //实例化对象 var User = new Class(); //静态方法 User.extend({ isName: function(){......}, isNum: function(){......} }); //实例方法 User.include({ add: function(){......}, delete: function(){......} });
4、基于原型的继承
var User = function(){}; User.prototype.show = function(){ console.log('----show----'); }; var Student = function(){}; //Student继承了User Student.prototype = new User(); Student.prototype.study = function(){ console.log('-----study-----'); }; var stu = new Student(); stu.show(); stu.study();
5、给Class增加继承
var Class = function(parent){ var kalss = function(){ this.init.apply(this, arguments); }; if(parent){ var subclass = function(){}; subclass.prototype = parent.prototype; klass.prototype = new subclass(); } klass.prototype.init = function(){}; klass.fn = klass.prototype; klass.fn.parent = klass; //这里可以参考github.com/maccman/super.js klass._super = klass.__proto__; //增加类属性 Klass.extend = function(obj){ var extended = obj.extended; for(var i in obj){ klass[i] = obj[i]; } if(extended)extended(klass); }; //增加实例属性 klass.include = function(obj){ var included = obj.included; for(var i in obj){ klass.fn[i] = obj[i]; } if(included) included(klass); }; return klass; };
三、事件监听
1、基础事件
/* * 事件 * * */ var Event = { //添加事件 addEvent: function(el, type, callback, useCapture){ if(el.addEventListener){ el.addEventListener(type, callback, !useCapture); }else{ el.attachEvent('on' + type, callback); } return callback; }, //删除事件 deleteEvent: function(el, type, callback, useCapture){ if(el.removeEventListener){ el.removeEventListener(type, callback, !useCapture); }else{ el.detachEvent('on' + type, callback); } }, //创建事件 createEvent: function(types){ if(document.createEvent){ return document.createEvent(types); }else{ return document.createEventObject(); } }, //触发事件 fireEvent: function(el, type, args, event){ args = args || {}; if(el.dispatchEvent){ event = document.createEvent('HTMLEvents'); event.initEvent(type, true, true); }else{ event = document.createEventObject(); } for(var i in args){ if(args.hasOwnProperty(i)){ event[i] = args[i]; } } if(el.dispatchEvent){ el.dispatchEvent(event); }else{ el.fireEvent('on' + type, event); } } };
2、订阅 & 发布
var PubSub = { sub: function(event, callback){ var calls = this._callbacks || (this._callbacks = {}); (this._callbacks[event] || (this._callbacks[event])).push(callback); return this; }, publish: function(){ var args = Array.prototype.slice.call(arguments, 0); var ev = args.shift(); var list, calls, i, l; if(!(calls = this._callbacks)) return this; if(!(list = this._callback[ev])) return this; for(i = 0, l = list.length; i < l; i++){ list[i].apply(this, args); } return this; } };
四、模型
1、模型的构建
var User = { records: [], fetchRemote: function(){...} }; 以上代码有几个优点 (0)子面量表达,那些属性和方法属于哪个对象,清晰明了; (1)属性保存在User命名空间下,可以减少命名冲突; (2)同时,我们可以很好的封装代码; But(世界上最怕的就是but了), 我们需要创建实例对象和实例方法。因此,我们改造: var User = function(name){ this.name = name || 'vczero'; } User.prototype.getName = function(){ return this.name; }
2、ORM(对象关系映射)
ORM可以将模型和数据服务结合在一起,任何模型实例的改变都会发起一个Ajax请求到服务器;或者说,将模型实例和HTML元素绑在一起。ORM的基础功能有CRUD数据、合法性校验、监听等。
ORM可以将模型和数据服务结合在一起,任何模型实例的改变都会发起一个ajax请求到服务器;或者说, 将模型实例和HTML元素绑在一起。ORM的基础功能有CRUD数据、合法性校验、监听等。 1、基于原型的继承(prototype-based) Object.create传入一个参数,返回新一个新对象(新对象的原型就是传入参数),也即继承于参数对象 if(typeof Object.create !== 'function'){ Object.create = function(o){ function F(){} F.prototype = o; return new F(); } } 现在,可以创建一个Model对象,将用于构建实例: var Model = { inherited: function(){}, created: function(){}, prototype: { init: function(){} }, //返回一个新对象,这个对象继承于Model create: function(){ var obj = Object.create(this); obj.parent = this; obj.prototype = obj.fn = Object.create(this.prototype); obj.created(); this.inherited(obj); return obj; }, //返回一个新对象,继承于Model.prototype,即Model的一个实例 init: function(){ var instance = Object.create(this.prototype); instance.pa
新闻热点
疑难解答