60行以内写mvc

标题党。几天前看到一个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的架构有很多,但基本原理都是一样的。