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

 更新时间:2016年06月07日 15:29:52   投稿:jingxian  
下面小编就为大家带来一篇mvvm双向绑定机制的原理和实现代码(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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双向绑定机制的原理和实现代码(推荐)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • firefox和IE系列的相关区别整理 以备后用

    firefox和IE系列的相关区别整理 以备后用

    firefox和IE系列的相关区别整理,整理相对来说还可以,但对于个别细节的处理不够完善。具体的可以参考脚本*之家以前发布的文章。
    2009-12-12
  • js版实现计算器功能

    js版实现计算器功能

    这篇文章主要为大家详细介绍了js版实现计算器功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Javascript判断文件是否存在(客户端/服务器端)

    Javascript判断文件是否存在(客户端/服务器端)

    这篇文章主要介绍了Javascript判断文件是否存在的方法适用于客户端、服务器端,远程文件,示例代码如下,需要的朋友可以参考下
    2014-09-09
  • 使用 Node.js 做 Function Test实现方法

    使用 Node.js 做 Function Test实现方法

    这篇文章介绍了Node.js 做 Function Test实现方法,有需要的朋友可以参考一下
    2013-10-10
  • js实现鼠标滑动到某个div禁止滚动

    js实现鼠标滑动到某个div禁止滚动

    这篇文章主要为大家详细介绍了js实现鼠标滑动到某个div禁止滚动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09
  • 浅谈在js传递参数中含加号(+)的处理方式

    浅谈在js传递参数中含加号(+)的处理方式

    下面小编就为大家带来一篇浅谈在js传递参数中含加号(+)的处理方式。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • 微信小程序点击滚动到指定位置的实现

    微信小程序点击滚动到指定位置的实现

    这篇文章主要介绍了微信小程序点击滚动到指定位置的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • js或css实现滚动广告的几种方案

    js或css实现滚动广告的几种方案

    今天无事逛网,突然发现了一个很有趣的事情,(也许只有我觉得有趣).我看到一图片竟然在我拖动滚动条的时候没有动,也许你会说我少见多怪,不信你去找个这样的我看看,很少有的,一般的都是一拖动图片就在那跳得厉害。
    2010-01-01
  • JS 中Proxy代理和 Reflect反射方法示例详解

    JS 中Proxy代理和 Reflect反射方法示例详解

    这篇文章主要为大家介绍了JS 中Proxy代理和 Reflect反射方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • 详解JS中continue关键字和break关键字的区别

    详解JS中continue关键字和break关键字的区别

    在javascript中continue的作用是退出当前次循环,break的作用则是一旦当前循环有break那么直接退出整个循环。本文将通过一些示例为大家详细讲讲二者的区别,感兴趣的可以了解一下
    2022-08-08

最新评论