mvvm双向绑定机制的原理和实现代码(推荐)


Posted in Javascript onJune 07, 2016

mvvm框架的双向绑定,即当对象改变时,自动改变相关的dom元素的值,反之,当dom元素改变时,能自动更新对象的值,当然dom元素一般是指可输出的input元素。

1. 首先实现单向绑定,在指定对象的属性值发生改变时触发callback函数。

2. 单向绑定可采用ES5新增的defineProperty实现(或defineProperties),用了ES5注定就不支持IE9以下了,为了防止递归死循环问题,原有属性需要剪切到一个私有属性中保存。

3. 循环调用defineProperty定义闭包时产生作用域的问题,为解决作用域变量对象的值会取到最后一次运行值问题,多定义一层立即调用的闭包函数将值传入。

4. 我们定义getFN和setFN函数用于在属性get和set的时候触发,它的功能是对私有属性__private的读写并触发回调函数通知UI层更新界面。

5.单向绑定实现完成后,实现反向的绑定,即UI层onchange之后触发更新数据,这个相对比较容易,在dom中通过自定义属性bindKey关联model的值变化,监听使用oninput事件,相比onchange的好处是可以实时变化不用等失焦,而且对右键粘贴、菜单粘贴,拖动文字进文本框等方式都可以触发,完全无死角,缺点是只支持IE9以上,但是在IE9以下有等价的onpropertychange可以用还是能兼容的。

6.总结,双向绑定的原理并不复杂,整体代码不超过50行,非常精简,不过还是有一些技术含量,下面是完整的代码,如果不想使用庞大的框架,可以用一下。ie9以下是不支持的,如要支持ie9以下可以使用avalon,它用vbs做了get,set存取器的封装,这点还是比较强大的。

html:

<div id="container">
  <p>
  name:<input type="text" bindkey="userName">
  </p>
  <p>
  age:<input type="text" bindkey="age">
  </p>
<div>

js:

<script type="text/javascript">
  window.Model={
    userName:"windy",
    age:34,
    skill:["javascript","html","css","jquery","node"],
    
  }
  function bindingModel(model,changeCallback){
    var propertiesMap={};
    model.__private={};
    function getFn(name){
      var result=this.__private[name]
      console.log("get value:"+name+"="+ result);
      return result;
    };
    function setFn(name,val){
      if(this.__private[name]!=val){
        console.log("set value:"+name+"="+val);
       
        this.__private[name]=val;

        if(changeCallback){
          changeCallback(name,val);
        }
      }
    };
    for(elem in model){
      if(model.hasOwnProperty(elem) && elem!="__private" && typeof(model[elem])!="function"){
        (function(propName,propValue){
          model.__private[propName]=propValue;// init value
          propertiesMap[propName]={
            get:function(){ return getFn.call(this,propName)},
            set:function(v){ return setFn.call(this,propName,v)},
            //value:model[elem],
            //writable: true,
            enumerable: true,
            configurable: true
          }
        })(elem,model[elem]);
      }
    }
    Object.defineProperties(model,propertiesMap)
    
  }
  function bindingBoth(model,dom){
    dom.find("[bindkey]").each(function(item){
      var key=$(this).attr("bindkey");
      $(this).val(model[key]);
      $(this).bind("input",function(){
        model[key]=$(this).val();
      })
    });
    bindingModel(model,function(name,val){
      var el=dom.find("[bindkey="+name+"]");
      if(el.val()!=val){
        el.val(val);
      }
      
    });
  }
  bindingBoth(window.Model,$("#container"))
  </script>

以上这篇mvvm双向绑定机制的原理和实现代码(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 函数式编程
Aug 16 Javascript
jquery ajax post提交数据乱码
Nov 05 Javascript
jquery获取元素值的方法(常见的表单元素)
Nov 15 Javascript
js中判断用户输入的值是否为空的简单实例
Dec 23 Javascript
javascript时间函数大全
Jun 30 Javascript
javascript实现禁止右键和F12查看源代码
Dec 26 Javascript
JS使用eval解析JSON的注意事项分析
Nov 14 Javascript
jquery实现多次上传同一张图片
Jan 09 Javascript
vue 项目如何引入微信sdk接口的方法
Dec 18 Javascript
Web安全之XSS攻击与防御小结
Dec 13 Javascript
Echart折线图手柄触发事件示例详解
Dec 16 Javascript
使用Vue CLI创建typescript项目的方法
Aug 09 Javascript
jQuery原理系列-常用Dom操作详解
Jun 07 #Javascript
浅析BootStrap栅格系统
Jun 07 #Javascript
浅谈jQuery 选择器和dom操作
Jun 07 #Javascript
BootStrap.css 在手机端滑动时右侧出现空白的原因及解决办法
Jun 07 #Javascript
DOM操作和jQuery实现选项移动操作的简单实例
Jun 07 #Javascript
Knockoutjs 学习系列(二)花式捆绑
Jun 07 #Javascript
Knockoutjs 学习系列(一)ko初体验
Jun 07 #Javascript
You might like
浅谈电磁辐射对健康的影响
2021/03/01 无线电
php 团购折扣计算公式
2011/11/24 PHP
PHP使用GIFEncoder类处理gif图片实例
2014/07/01 PHP
Laravel 5 学习笔记
2015/03/06 PHP
php使用array_chunk函数将一个数组分割成多个数组
2018/12/05 PHP
不同浏览器的怪癖小结
2010/07/11 Javascript
JavaScript原生对象之Date对象的属性和方法详解
2015/03/13 Javascript
Jquery遍历Json数据的方法
2015/04/20 Javascript
浅谈JS函数定义方式的区别
2016/10/30 Javascript
BootStrap Table 后台数据绑定、特殊列处理、排序功能
2017/05/27 Javascript
解决Vue页面固定滚动位置的处理办法
2017/07/13 Javascript
bootstrap实现点击删除按钮弹出确认框的实例代码
2018/08/16 Javascript
关于vue v-for 循环问题(一行显示四个,每一行的最右边那个计算属性)
2018/09/04 Javascript
如何根据业务封装自己的功能组件
2019/04/19 Javascript
仿ElementUI实现一个Form表单的实现代码
2019/04/23 Javascript
详解element上传组件before-remove钩子问题解决
2020/04/08 Javascript
JavaScript冒泡算法原理与实现方法深入理解
2020/06/04 Javascript
[02:37]2018DOTA2亚洲邀请赛赛前采访 VP.no[o]ne心中最强SOLO是谁
2018/04/04 DOTA
Python格式化css文件的方法
2015/03/10 Python
Python实现线程池代码分享
2015/06/21 Python
Python SMTP发送邮件遇到的一些问题及解决办法
2018/10/24 Python
Python从list类型、range()序列简单认识类(class)【可迭代】
2019/05/31 Python
python中time库的实例使用方法
2019/10/31 Python
基于python3抓取pinpoint应用信息入库
2020/01/08 Python
pytorch中的weight-initilzation用法
2020/06/24 Python
简单了解Python字典copy与赋值的区别
2020/09/16 Python
python+requests实现接口测试的完整步骤
2020/10/27 Python
Django执行源生mysql语句实现过程解析
2020/11/12 Python
CSS3实现的炫酷菜单代码分享
2015/03/12 HTML / CSS
公务员年总结的自我评价
2013/10/25 职场文书
团日活动总结书格式
2014/05/08 职场文书
商品陈列协议书
2014/09/29 职场文书
班主任2015新年寄语
2014/12/08 职场文书
工作迟到检讨书范文
2015/05/06 职场文书
高质量“欢迎词”
2019/04/03 职场文书
优秀新员工事迹材料
2019/05/13 职场文书