js mvvm:闲来无事,实现一个只具最基本数据双向绑定的mvvm

近期项目内用knockoutjs。

想模拟实现数据双向绑定的基本功能。

只具有最基本的功能,且很多细节未曾考虑,也未优化精简。

能想到的缺少的模块

1事件监听,自定义访问器事件

2模版

3父子级

编码时,有两个循环陷阱。

只依赖浏览器,打开即可运行。

工作以后端和数据为主,前端较生疏,将就看吧

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8 <br>
 9 <lable>name</lable><input type="text" data-bind="name" value="old"/><br>
10 <lable>age</lable><input  type="text" data-bind="value" value="18"/><br>
11 <!--<lable>sex</lable><input  type="text"  value="男"/><br>-->
12 <input type="button" onclick="mvvm.bind(window.ViewModel)" value="绑定数握">
13 <input type="button" onclick="mvvm.Saybind(window.ViewModel)" value="查看数据">
14 <input type="button" onclick="window.ViewModel.changename()" value="改名">
15 
16 </body>
17 <script>
18     (function(win){
19         window.mvvm={
20             bind:function(obj){
21                 var inputs = document.getElementsByTagName("input");
22                 if(!obj.hasini){
23                     alert("初始化访问器")
24                     //为model添加访问器,目的,是model时更新UI
25                     for (var Property in obj) {
26                         (function(){
27                             var proname=Property;
28                             var priname="_"+proname;
29                             if(typeof obj[Property]!="function"){
30                                 obj[priname]=obj[proname];
31                                 obj[proname]=null;
32                                 var setget={
33                                     get: function () {
34                                         return obj[priname]
35                                     },
36                                     set:function (value) {
37                                         obj[priname] = value;
38                                         for (var i = 0; i < inputs.length; i++) {
39                                             var att = inputs[i].getAttribute("data-bind");
40                                             if (att == proname) {
41                                                 inputs[i].value = obj[priname];
42                                                 break;
43                                             }
44                                         }
45                                     }
46                                 }
47                                 Object.defineProperty(obj, proname, setget);
48                             }
49                         })(obj,Property)
50                     }
51                 }
52                 obj.hasini=true;
53                 alert("初始化完成")
54                 //为UI绑定model的值,并为UI添加事件,修改UI时更新Model值。
55                 for (var i = 0; i < inputs.length; i++) {
56                     var inputdom = inputs[i];
57                     var att = inputdom.getAttribute("data-bind");
58                     if (att != null) {
59                         for (var Property in obj) {
60                             if (Property == att) {
61 //                      绑定属性
62                                 inputdom.value = obj[Property];
63 //                      绑定事件
64                                 inputdom.onchange = function () {
65                                     obj[this.getAttribute("data-bind")] = this.value;
66                                 }
67                             }
68                         }
69                     }
70                 }
71             },
72             Saybind:function(obj){
73                 alert(obj.toString());
74             }
75         }
76 
77     })(window);
78     var ViewModel={
79         name:"cui",
80         value:"24",
81         toString:function(){
82             var ps="";
83             for(var Property in this){
84                 if(typeof this[Property]!="function")
85                     ps+=Property+":"+this[Property]+";"
86             }
87             return ps;
88         },
89         changename:function(){
90             this.name="daming";
91         }
92     } ;
93 
94 </script>
95 </html>