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 相关文章推荐
Firefox div高度自适应
Apr 28 Javascript
JS 控制小数位数的实现代码
Aug 02 Javascript
IE网页js语法错误2行字符1、FF中正常的解决方法
Sep 09 Javascript
jquery更换文章内容与改变字体大小代码
Sep 30 Javascript
jquery及js实现动态加载js文件的方法
Jan 21 Javascript
AngularJS基础 ng-include 指令简单示例
Aug 01 Javascript
jQuery使用animate实现ul列表项相互飘动效果示例
Sep 16 Javascript
Bootstrap select多选下拉框实现代码
Dec 23 Javascript
利用js的闭包原理做对象封装及调用方法
Apr 07 Javascript
微信小程序getPhoneNumber获取用户手机号
Sep 29 Javascript
解析vue data不可以使用箭头函数问题
Jul 03 Javascript
原生javascript运动函数的封装示例【匀速、抛物线、多属性的运动等】
Feb 23 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
海贼王动画变成“真人”后,凯多神还原,雷利太帅了!
2020/04/09 日漫
php下图片文字混合水印与缩略图实现代码
2009/12/11 PHP
PHP利用header跳转失效的解决方法
2014/10/24 PHP
PHP中$_SERVER使用说明
2015/07/05 PHP
ThinkPHP中Widget扩展的两种写法及调用方法详解
2017/05/04 PHP
thinkPHP3.2.3实现阿里大于短信验证的方法
2018/06/06 PHP
仿新浪微博返回顶部的jquery实现代码
2012/10/01 Javascript
div拖拽插件——JQ.MoveBox.js(自制JQ插件)
2013/05/17 Javascript
JQuery页面图片切换和新闻列表滚动效果的具体实现
2013/09/26 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
2015/02/04 Javascript
浅谈被jQuery抛弃的函数及替代函数
2015/05/03 Javascript
js带点自动图片轮播幻灯片特效代码分享
2015/09/07 Javascript
JavaScript根据CSS的Media Queries来判断浏览设备的方法
2016/05/10 Javascript
jQuery EasyUI编辑DataGrid用combobox实现多级联动
2016/08/29 Javascript
angular2 ng2-file-upload上传示例代码
2018/08/23 Javascript
微信小程序支付PHP代码
2018/08/23 Javascript
babel7.x和webpack4.x配置vue项目的方法步骤
2019/05/12 Javascript
vue-next/runtime-core 源码阅读指南详解
2019/10/25 Javascript
vue简单封装axios插件和接口的统一管理操作示例
2020/02/02 Javascript
给Python的Django框架下搭建的BLOG添加RSS功能的教程
2015/04/08 Python
python通过百度地图API获取某地址的经纬度详解
2018/01/28 Python
Python解决两个整数相除只得到整数部分的实例
2018/11/10 Python
Python使用sqlalchemy模块连接数据库操作示例
2019/03/13 Python
给大家整理了19个pythonic的编程习惯(小结)
2019/09/25 Python
pytorch模型预测结果与ndarray互转方式
2020/01/15 Python
惠普美国官方商店:HP Official Store
2016/08/28 全球购物
椰子猫砂:CatSpot
2018/08/27 全球购物
日本必酷网络直营店:Biccamera
2019/03/23 全球购物
面料业务员岗位职责
2013/12/26 职场文书
文秘档案管理岗位职责
2014/03/06 职场文书
预备党员公开承诺书
2014/05/28 职场文书
一次性工伤赔偿协议书范本
2014/11/25 职场文书
2014年远程教育工作总结
2014/12/09 职场文书
保研推荐信格式
2015/03/25 职场文书
六一儿童节新闻稿
2015/07/17 职场文书
《吸血鬼幸存者》新内容发布 追加多个全新模式
2022/04/07 其他游戏