凯发娱发k8

如何实现一个简单的mvvm框架 -凯发娱发k8

2023-10-15

接触过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
< script type="text/javascript" src="./event.js">
< script type="text/javascript" src="./model.js">
< script type="text/javascript" src="./view.js">
< 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">
< div id="textid">0

< /div>
< script type="text/javascript" src="./index.js">
< 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框架的相关教程结束。

网站地图