一个简单的mvvm demo-avalon原理

在阅读了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微信

扫码关注w3ctech微信公众号

共收到1条回复

  • 切换次数多了很卡

    回复此楼

AltStyle によって変換されたページ (->オリジナル) /