仅30行代码实现Javascript中的MVC(2)

// html: <div bind="model1"></div> <div bind="model1"></div> // 逻辑代码: new Controller(function (models) { var model1 = models.model1; model1.set('this is a div'); });

就这么简单吗?就这么简单。MVC的本质就是在controller中完成业务逻辑,并对model进行修改,同时model的改变引起view的自动更新,这些逻辑在上面的代码中都有所体现,并且支持多个view、多个model。虽然不足以用于生产项目,但是希望对大家的MVC学习多少有些帮助。

整理后去掉注释的"框架"代码:

function Model(value) { this._value = typeof value === 'undefined' ? '' : value; this._listeners = []; } Model.prototype.set = function (value) { var self = this; self._value = value; setTimeout(function () { self._listeners.forEach(function (listener) { listener.call(self, value); }); }); }; Model.prototype.watch = function (listener) { this._listeners.push(listener); }; Model.prototype.bind = function (node) { this.watch(function (value) { node.innerHTML = value; }); }; function Controller(callback) { var models = {}; var views = Array.prototype.slice.call(document.querySelectorAll('[bind]'), 0); views.forEach(function (view) { var modelName = view.getAttribute('bind'); models[modelName] = models[modelName] || new Model(); models[modelName].bind(view); }); callback.call(this, models); }

后记:

笔者在学习flux和redux的过程中,虽然掌握了工具的使用方法,但只是知其然而不知其所以然,对ReactJS官方文档中一直强调的 "Flux eschews MVC in favor of a unidirectional data flow" 不甚理解,始终觉得单向数据流和MVC并不冲突,不明白为什么在ReactJS的文档中这二者会被对立起来,有他无我,有我无他(eschew,避开)。终于下定决心,回到MVC的定义上重新研究,虽然平日工作里大大咧咧复制粘贴,但是咱们偶尔也得任性一把,咬文嚼字一番,对吧?这样的方式也的确帮助了我对于这句话的理解,这里可以把自己的思考分享给大家:之所以觉得MVC和flux中的单向数据流相似,可能是因为没有区分清楚MVC和观察者模式的关系造成的——MVC是基于观察者模式的,flux也是,因此这种相似性的由来是观察者模式,而不是MVC和flux本身。这样的理解也在四人组的设计模式原著中得到了印证:"The first and perhaps best-known example of the Observer pattern appears in Smalltalk Model/View/Controller (MVC), the user interface framework in the Smalltalk environment [KP88]. MVC's Model class plays the role of Subject, while View is the base class for observers. "。

如果读者有兴趣在这样一个原型玩具的基础上继续拓展,可以参考下面的一些方向:

1. 实现对input类标签的双向绑定

2. 实现对controller所控制的scope的精准控制,这里一个controller就控制了整个dom树

3. 实现view层有关dom node隐藏/显示、创建/销毁的逻辑

4. 集成virtual dom,增加dom diff的功能,提高渲染效率

5. 提供依赖注入功能,实现控制反转

6. 对innerHTML的赋值内容进行安全检查,防止恶意注入

7. 实现model collection的逻辑,这里每个model只有一个值

8. 利用es5中的setter改变set方法的实现,使得对model的修改更加简单

9. 在view层中增加对属性和css的控制

10.支持类似AngularJS中双大括号的语法,只绑定部分html

……

一个完善的框架要经过无数的提炼和修改,这里只是最初最初的第一步,道路还很漫长,希望大家再接再厉。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgwygs.html