在阅读了avalon源码之后,依照其劫持get&&set及观察者模式,实现的一个model-view-viewModel例子,来帮助大家更好的理解流程mvvm框架avalon
<!DOCTYPE html>
<html>
<head>
<title>部分原理 - 第二版</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<!--view-->
<div id="name">
{{name}} - {{age}} - {{country}}
</div>
<p>选择切换</p>
<select onChange="change.call(this,event)">
<option>skipper1-1-China1</option>
<option>skipper2-2-China2</option>
<option>skipper3-3-China3</option>
<option>skipper4-4-China4</option>
<option>skipper5-5-China5</option>
</select>
<script>
// 观察者
var eventCenter = {
events: {},
// 订阅
add: function(e, callback) {
if(!this[e]) this[e] = []
for(var i = 0, len = this[e].length; i < len; i++) {
if(this[e][i] === callback) return
}
this[e].push(callback)
},
// 分发事件
fire: function(e, data) {
if(this[e]) {
for(var i = 0, len = this[e].length; i < len; i++) {
this[e][i](data)
}
}
}
};
// model
var model = {};
// view-model 劫持set & get
// 不过第三版里面已经用 Object.observe
function addProp(model, key) {
Object.defineProperty(model, key, {
// get,提取依赖,将视图更新函数添加到观察者侦听队列
get: function() {
var c = arguments.callee.caller,
arg = c.arguments
eventCenter.add(key, function() {
c.apply(null, arg)
})
return this["$" + key]
},
// set,值被修改后,触发视图更新函数
set: function(v) {
this["$" + key] = v;
eventCenter.fire(key, v)
}
})
}
addProp(model, "name")
addProp(model, "age")
addProp(model, "country")
// ---
// view-model扫描
function scan(element, model) {
var html = element.innerHTML,
all = html.split(/\{\{|\}\}/),
flag = 1
element.appendChild(document.createElement("p"))
for(var i = 1, len = all.length; i < all.length; i++) {
// 插值表达式
if(flag == 1) {
flag = 0;
(function() {
var node = document.createTextNode("");
element.appendChild(node);
// 视图刷新函数
(function(key, node) {
node.nodeValue = model[key]
})(all[i], node)
node = null
})()
// 普通文本
} else {
flag = 1
var node = document.createTextNode(all[i]);
element.appendChild(node);
}
}
}
model.name = "nobody"
model.age = "secret"
model.country = "**"
scan(document.getElementById("name"), model)
function change() {
var h = this.children[this.selectedIndex].innerHTML.split("-"),
dict = ["name", "age", "country"]
for(var i in dict) {
model[dict[i]] = h[i]
}
}
</script>
</body>
</html>
扫码关注w3ctech微信公众号
切换次数多了很卡
共收到1条回复