接触过web开发的同学想必都接触过MVVM,业界著名的MVVM框架就有AngelaJS。今天闲来无事,决定自己实现一个简单的MVVM框架玩一玩。所谓简单,就是仅仅实现一个骨架,仅表其意,不摹其形。

分析

MVVM最大的特点莫过于双向绑定了,数据的变化能及时更新到视图上,同时视图的变化也能及时的更新到数据中。

那么怎么实现这样的双向绑定呢?最直接的方式莫过于事件了。

所以,我们需要实现一个事件的订阅与分发机制,这个功能很常见,网上搜一搜一大堆。

有了这么一套事件的订阅与分发机制,我们就可以通过它将Model和View关联起来,这样不管是Model还是View有变化,都可以通过事件通知到对方了。

实现

首先要实现一套事件的订阅与分发机制,直接贴代码了:

function Event() {
this.handlers = {};
} Event.prototype.on = function (eventName, handler) {
if (!this.handlers) {
this.handlers = {};
}
if (this.handlers[eventName]) {
this.handlers[eventName].push(handler);
} else {
this.handlers[eventName] = [handler];
}
} Event.prototype.fire = function (eventName, eventData) {
if (this.handlers[eventName]) {
this.handlers[eventName].forEach(function (handler) {
handler(eventData);
});
}
} Event.prototype.off = function (eventName, handler) {
if (this.handlers[eventName]) {
for (var i = 0; i < this.handlers[eventName].length; i++) {
if (this.handlers[eventName][i] === handler) {
this.handlers[eventName].splice(i, 1);
}
}
}
}

上诉代码实现了某个事件的监听、触发与移除操作。

有了事件,如何将其与View和Model结合起来呢? 继承。

function Model(data) {
this.data = data;
} Model.prototype = new Object(Event.prototype);
Model.prototype.constructor = Model; Model.prototype.set = function (key, value) {
if (this.data[key]) {
this.data[key] = value;
}
this.fire("change", value);
} Model.prototype.get = function (key) {
console.log("key: ", key, " value: ", this.data[key]);
}
function View(model, el) {
this.el = el;
this.model = model; this.init();
} View.prototype.init = function () {
var me = this;
this.model.on("change", function (value) {
me.model.get("value");
if (me.el.type === "text") {
me.el.value = value;
} else {
me.el.innerText = value;
}
});
if (this.el.type === "text") {
this.el.addEventListener("change", function () {
me.model.set("value", this.value);
});
} else {
this.el.addEventListener("click", function () {
var num = new Number(this.innerText || 0);
me.model.set("value", num + 1);
});
} }

View中为了简单处理,直接进行了硬编码,实际应用过程中需要详细处理。

到此,Model和View都有了,下面再加一段代码将他们关联起来:


function MVVM() {
this.cache = {};
} MVVM.prototype.bind = function (data, el) {
var model = new Model(data);
var view = new View(model, el);
var key = "key_" + (new Date()).getTime();
this.cache[key] = {
model: model,
view: view
};
}

测试代码如下:

< !DOCTYPE html>
< html>
< head>
< title>MVVM</title>
< script type="text/javascript" src="./Event.js"></script>
< script type="text/javascript" src="./Model.js"></script>
< script type="text/javascript" src="./View.js"></script>
< style type="text/css">
#inputId {
width: 300px;
height: 30px;
border: 1px solid grey;
margin: 10px;
}
#textId {
width: 300px;
height: 100px;
text-align: center;
border: 1px solid black;
line-height: 100px;
font-size: 20px;
}
< /style>
< /head>
< body>
< div>
< input id="inputId" type="text"></input>
< div id="textId">0</div>
< /div>
< script type="text/javascript" src="./index.js"></script>
< script type="text/javascript">
var mvvm = new MVVM();
mvvm.bind({
value: "text input"
}, document.getElementById("inputId"));
mvvm.bind({
value: "div text"
}, document.getElementById("textId"));
< /script>
< /body>
< /html>

测试代码中绑定了一个输入框和一个div,当输入框中值发生改变时,Model中的值也会相应改变(查看控制台打印信息)。当点击div时,div中的文本数字会加一,对应Model中的数据也会改变。

到此所有的功能就实现完了,虽说简单了点,但是基本意思算是都到了,收工~~。

如何实现一个简单的MVVM框架的更多相关文章

  1. 基于vue实现一个简单的MVVM框架(源码分析)

    不知不觉接触前端的时间已经过去半年了,越来越发觉对知识的学习不应该只停留在会用的层面,这在我学jQuery的一段时间后便有这样的体会. 虽然jQuery只是一个JS的代码库,只要会一些JS的基本操作学 ...

  2. 230行实现一个简单的MVVM

    作者:mirone链接:https://zhuanlan.zhihu.com/p/24451202来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. MVVM这两年在前端届 ...

  3. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  4. 一个简单的web框架实现

    一个简单的web框架实现 #!/usr/bin/env python # -- coding: utf-8 -- __author__ = 'EchoRep' from wsgiref.simple_ ...

  5. 自己实现的一个简单的EF框架(反射实现)

    我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...

  6. koa2源码解读及实现一个简单的koa2框架

    阅读目录 一:封装node http server. 创建koa类构造函数. 二:构造request.response.及 context 对象. 三:中间件机制的实现. 四:错误捕获和错误处理. k ...

  7. Core1.1环境下,自己实现的一个简单的CRUD框架(反射实现)

    我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...

  8. 动手造轮子:实现一个简单的 AOP 框架

    动手造轮子:实现一个简单的 AOP 框架 Intro 最近实现了一个 AOP 框架 -- FluentAspects,API 基本稳定了,写篇文章分享一下这个 AOP 框架的设计. 整体设计 概览 I ...

  9. 徒手撸一个简单的RPC框架

    来源:https://juejin.im/post/5c4481a4f265da613438aec3 之前在牛逼哄哄的 RPC 框架,底层到底什么原理得知了RPC(远程过程调用)简单来说就是调用远程的 ...

随机推荐

  1. How do I create a .pyc file?

    Python automatically compiles your script to compiled code, so called byte code, before running it. ...

  2. Android自动提示控件:AutoCompleteTextView和MultiAutoCompleteTextView

    在输入框中输入我们想要输入的信息就会出现其他与其相关的提示信息,这种效果在Android中是用AutoCompleteTextView实现的. 一.AutoCompleteTextView:单一匹配 ...

  3. Mongo Windows 基本使用入门

    1.安装https://www.mongodb.com/download-center#community注意:安装 "install mongoDB compass" 不勾选下载 ...

  4. sqlServer2008技术内幕笔记总结(实用的sql方法总结)

    over函数的使用: 1.可以实现基于什么求和,省去group by: select xingming,xingbie,COUNT(*) over() as '总人数' from jbxx_xuesh ...

  5. .Net Core 项目部署IIS简单步骤

    1.新建一个解决方案: 我习惯会把运行文件移至一级目录 然后清除CoreTest 文件夹里面的文件 2.在解决方案中新建一个项目 点击确认有,这里有几种选择类型,我一般选择空类型(这里需要注意一下,空 ...

  6. Android系列一: 环境搭建

      相关软件 JAVA  JDKAndroid StudioHAXM JDK的安装和Java环境变量的设置 1.JDK下载地址: http://www.oracle.com/technetwork/j ...

  7. android android studio

     android studio 一.安装及步骤: Android Studio安装: java jdk安装: jdk环境变量配置: 二.遇到的问题: 1.缺少jvm或java jdk路径不对,请指定正 ...

  8. java设计模式 策略

    什么是策略设计模式? 世界永远都在变,唯一不变的就是变本身 举个生活中的例子,小时候玩的游戏中,Sony的PSP提供了统一的卡槽接口,玩家只要更换卡带就可以达到更换游戏的目的,做到了一机多用 特工执行 ...

  9. 【转】C#、面向对象、设计模式学习

    源地址:http://www.cnblogs.com/cj723/archive/2007/04/02/697431.html

  10. flink学习笔记-数据源(DataSource)

    说明:本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKh ...