标题党。几天前看到一个30行写mvc的文章,东施效颦,也动手写了个60行的,功能上略微扩充一些,记录下来,后面有时间可以继续优化。
mvc其实是一个观察者模式。view来监听model,所以当model的数据有变化的时候,view可以自动更新视图。
既然view来监听model,那么是不是可以扩展一下,如果页面上多个模块同时使用一个数据源,也就是同时使用一个model的时候,是否可以让这些模块的
view都来监听这一个model,这样当model的数据发生变化时,监听该model的views们 视图同时也都发生了变化呢,肯定是可以的。
根据这个思路,花了差不多两个晚上的时间,写完了一个基本的雏形。
先看model。
function Model (value) { this.value = value || ''; // idList保存的是 监听该model的view的id, 该idList示例:[{viewid1: {event1: function(){.....}}},{viewid2: {}}] this.idList = []; }; // 当model的数据变化的时候,监听model的view发生对应的变化 Model.prototype.changeValue = function (value) { var that = this; that.value = value; var idList = that.idList; for (var k in idList) { if (idList[k]) { for (var j in idList[k]) { idList[k][j].call(this, value); } } } };
下面是view
function View (id, eventList) { this.id = id; this.eventList = eventList || {}; } // view基于model的事件,当model的数据变化时,view会通过这些事件 // 进行视图的改变 View.prototype.setEventList = function (eventList, model) { var that = this; that.eventList = eventList; that.subscribeModel(model); }; // view订阅model 这样可以保证多个view公用一个model View.prototype.subscribeModel = function (model) { var that = this; var id = that.id; model.idList[id] = that.eventList; };
view里面并没有什么过于复杂的原理。
最后是controller,其实这个controller 可扩展性是很强的,因为只是简单的练习,controller里我并没有加太多的东西。
function Controller (model, view) { this.model = model; this.view = view; } Controller.prototype.trigger = function () { this.view.subscribeModel(this.model); };
写了点html实验一下 OK的
// 以下是测试的代码 var view = new View ('block', { 'changeContent': function (data) { document.getElementById('block').innerHTML = data; } }); var model = new Model(); var controller = new Controller(model, view); controller.trigger(); model.changeValue('data111');
这里是有个问题的,就是当model里有默认的数据时,是没有去渲染view的,后续可以再修改。
通过这个简单的例子,主要是更加清楚model和view的关系。目前机遇mv的架构有很多,但基本原理都是一样的。