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 相关文章推荐
Jsonp 跨域的原理以及Jquery的解决方案
May 18 Javascript
cnblogs中在闪存中屏蔽某人的实现代码
Nov 14 Javascript
强大的jquery插件jqeuryUI做网页对话框效果!简单
Apr 14 Javascript
使用js写的一个简易的投票
Nov 27 Javascript
jquery解析xml字符串示例分享
Mar 25 Javascript
JS实现网页上随滚动条滚动的层效果代码
Nov 04 Javascript
node.js+express制作网页计算器
Jan 17 Javascript
完美解决JS文件页面加载时的阻塞问题
Dec 18 Javascript
详解extract-text-webpack-plugin 的使用及安装
Jun 12 Javascript
微信上传视频文件提示(推荐)
Nov 22 Javascript
vue 实现cli3.0中使用proxy进行代理转发
Oct 30 Javascript
微信小程序实现锚点跳转
Nov 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
php判断当前用户已在别处登录的方法
2015/01/06 PHP
分享一个Laravel好用的Cache宏
2015/03/02 PHP
带你了解PHP7 性能翻倍的关键
2015/11/19 PHP
php提交过来的数据生成为txt文件
2016/04/28 PHP
Laravel 队列使用的实现
2019/01/08 PHP
JQuery给元素绑定click事件多次执行的解决方法
2014/05/29 Javascript
Javascript中使用parseInt函数需要注意的问题
2015/04/02 Javascript
JavaScript中调用函数的4种方式代码实例
2015/07/08 Javascript
javascript如何写热点图
2015/12/08 Javascript
jquery实用技巧之输入框提示语句
2016/07/28 Javascript
js多个物体运动功能实例分析
2016/12/20 Javascript
详解require.js配置路径的用法和css的引入
2017/09/06 Javascript
Web安全之XSS攻击与防御小结
2018/12/13 Javascript
Vue 权限控制的两种方法(路由验证)
2019/08/16 Javascript
JavaScript Array对象基本方法详解
2019/09/03 Javascript
layui实现根据table数据判断按钮显示情况的方法
2019/09/26 Javascript
Python写的Tkinter程序屏幕居中方法
2015/03/10 Python
python实现简单五子棋游戏
2019/06/18 Python
如何在Django配置文件里配置session链接
2019/08/06 Python
python3应用windows api对后台程序窗口及桌面截图并保存的方法
2019/08/27 Python
python的range和linspace使用详解
2019/11/27 Python
python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例
2020/03/08 Python
python mock测试的示例
2020/10/19 Python
python中round函数保留两位小数的方法
2020/12/04 Python
基于 HTML5 WebGL 实现的医疗物流系统
2019/10/08 HTML / CSS
Crocs美国官方网站:卡骆驰洞洞鞋
2017/08/04 全球购物
美国球鞋寄卖网站:Stadium Goods
2018/05/09 全球购物
和平主题的演讲稿
2014/01/12 职场文书
歌唱比赛获奖感言
2014/01/21 职场文书
社区党总支书记先进事迹材料
2014/01/24 职场文书
《识字五》教学反思
2014/03/01 职场文书
硕士研究生求职自荐信范文
2014/03/11 职场文书
旷课检讨书范文
2014/10/30 职场文书
写给纪委的违纪检讨书
2015/05/05 职场文书
python用海龟绘图写贪吃蛇游戏
2021/06/18 Python
Python实现归一化算法详情
2022/03/18 Python