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 相关文章推荐
YUI 读码日记之 YAHOO.lang.is*
Mar 22 Javascript
一个报数游戏js版(约瑟夫环问题)
Aug 05 Javascript
js取两个数组的交集|差集|并集|补集|去重示例代码
Aug 07 Javascript
jquery插件splitScren实现页面分屏切换模板特效
Jun 16 Javascript
js实现图片轮播效果
Dec 19 Javascript
jQuery获得字体颜色16位码的方法
Feb 20 Javascript
Node.js操作Firebird数据库教程
Mar 04 Javascript
JS/jQuery实现DIV延时几秒后消失或显示的方法
Feb 12 jQuery
通过jquery获取上传文件名称、类型和大小的实现代码
Apr 19 jQuery
微信小程序如何修改本地缓存key中单个数据的详解
Apr 26 Javascript
js中arguments对象的深入理解
May 14 Javascript
layuiAdmin循环遍历展示商品图片列表的方法
Sep 16 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
微信公众号OAuth2.0网页授权问题浅析
2017/01/21 PHP
PHP程序员必须知道的两种日志实例分析
2020/05/14 PHP
PHP+Redis事务解决高并发下商品超卖问题(推荐)
2020/08/03 PHP
javascript 支持ie和firefox杰奇翻页函数
2008/07/22 Javascript
javascript getElementsByTagName
2011/01/31 Javascript
基于jquery的防止大图片撑破页面的实现代码(立即缩放)
2011/10/24 Javascript
获取元素距离浏览器周边的位置的方法getBoundingClientRect
2013/04/17 Javascript
jquery ajax修改全局变量示例代码
2013/11/08 Javascript
根据表格中的某一列进行排序的javascript代码
2013/11/29 Javascript
bootstrap——bootstrapTable实现隐藏列的示例
2017/01/14 Javascript
canvas绘制表盘时钟
2017/01/23 Javascript
使用BootStrap实现标签切换原理解析
2017/03/14 Javascript
微信小程序中button组件的边框设置的实例详解
2017/09/27 Javascript
详解设置Webstorm 利用babel将ES6自动转码成ES5
2017/12/20 Javascript
webpack常用构建优化策略小结
2019/11/21 Javascript
Python操作RabbitMQ服务器实现消息队列的路由功能
2016/06/29 Python
python控制windows剪贴板,向剪贴板中写入图片的实例
2018/05/31 Python
解决python3 pika之连接断开的问题
2018/12/18 Python
python实现海螺图片的方法示例
2019/05/12 Python
Appium+python自动化怎么查看程序所占端口号和IP
2019/06/14 Python
完美解决python3.7 pip升级 拒绝访问问题
2019/07/12 Python
python 列表推导式使用详解
2019/08/29 Python
解决pycharm编辑区显示yaml文件层级结构遇中文乱码问题
2020/04/27 Python
LUISAVIAROMA德国官网:时尚奢侈品牌购物网站
2020/11/12 全球购物
车祸赔偿收入证明
2014/01/09 职场文书
国际贸易求职信
2014/07/05 职场文书
家具公司总经理岗位职责
2014/07/08 职场文书
升国旗演讲稿
2014/09/05 职场文书
学习党的群众路线教育实践活动剖析材料
2014/10/13 职场文书
优秀班组申报材料
2014/12/25 职场文书
劳动仲裁调解书
2015/05/20 职场文书
英语专业毕业论文答辩开场白
2015/05/27 职场文书
村主任当选感言
2015/08/01 职场文书
Python网络编程之ZeroMQ知识总结
2021/04/25 Python
python识别围棋定位棋盘位置
2021/07/26 Python
微软Win11有哪些隐藏功能? windows11多个功能汇总
2021/11/21 数码科技