当前位置:首页 > javascript技术文章 > JavaScript中双向数据绑定详解

深入理解JavaScript中双向数据绑定

  • 发布时间:
  • 作者:码农之家原创
  • 点击:157

这篇文章主要知识点是关于js、双向数据绑定、的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

HTML5+CSS3+JavaScript从入门到精通
  • 类型:web开发大小:186 MB格式:PDF作者:未来科技
立即下载

JavaScript中双向数据绑定详解

双向数据绑定指的是将对象属性变化绑定到UI,或者反之。换句话说,如果我们有一个拥有name属性的user对象,当我们给user.name赋予一个新值是UI也会相应的显示新的名字。同样的,如果UI包括了一个输入字段用来输入用户名,输入一个新的值会导致user对象中的那么属性发生变化。

许多流行的客户端JavaScript框架例如Ember.js,AngularJS以及KnockoutJS都将双向数据绑定作为自己的头号特性。但是这并不意味着从零开始实现双向数据绑定就很困难,同样的当我们需要双向数据绑定时并不是只能够选择这些框架其中的一个。双向数据绑定底层的思想非常的基本,它可以被压缩成为三个步骤:

1.我们需要一个方法来识别哪个UI元素被绑定了相应的属性

2.我们需要监视属性和UI元素的变化

3.我们需要将所有变化传播到绑定的对象和元素

虽然实现的方法有很多,但是最简单也是最有效的途径是使用发布者-订阅者模式。思想很简单:我们可以使用自定义的data属性在HTML代码中指明绑定。所有绑定起来的JavaScript对象以及DOM元素都将“订阅”一个发布者对象。任何时候如果JavaScript对象或者一个HTML输入字段被侦测到发生了变化,我们将代理事件到发布者-订阅者模式,这会反过来将变化广播并传播到所有绑定的对象和元素。

使用jQuery的简单实现

使用jQuery来实现双向数据绑定非常的直接且简单,因为这个流行的库能够是我们轻松的订阅和发布DOM事件,以及我们自定义的事件:

function DataBinder(object_id){
 //使用一个jQuery对象作为简单的订阅者发布者
 var pubSub = jQuery({});

 //我们希望一个data元素可以在表单中指明绑定:data-bind-<object_id>="<property_name>"  

 var data_attr = "bind-" + object_id,
   message = object_id + ":change";

 //使用data-binding属性和代理来监听那个元素上的变化事件
 // 以便变化能够“广播”到所有的关联对象 

 jQuery(document).on("change","[data-" + data_attr + "]",function(evt){
  var input = jQuery(this);
  pubSub.trigger(message, [ $input.data(data_attr),$input.val()]);
 });

 //PubSub将变化传播到所有的绑定元素,设置input标签的值或者其他标签的HTML内容 

 pubSub.on(message,function(evt,prop_name,new_val){
  jQuery("[data-" + data_attr + "=" + prop_name + "]").each(function(){
  var $bound = jQuery(this);

  if($bound.is("input,text area,select")){
   $bound.val(new_val);
  }else{
   $bound.html(new_val);
  }
  });
 });

 return pubSub;
}

在这个实验中可以按照以下代码简单的实现一个User模型:

function User(uid){
 var binder = new DataBinder(uid),

  user = {
   atttibutes: {},

   //属性设置器使用数据绑定器PubSub来发布变化 

   set: function(attr_name,val){
    this.attriures[attr_name] = val;
    binder.trigger(uid + ":change", [attr_name, val, this]);
   },

   get: function(attr_name){
    return this.attributes[attr_name];
   },

   _binder: binder
  };

  binder.on(uid +":change",function(vet,attr_name,new_val,initiator){
   if(initiator !== user){
    user.set(attr_name,new_val);
   }
  })
}

现在,无论我们什么时候想把模型的属性绑定到UI的一部分上,我们只需要在相应的HTML元素上设置一个合适的data属性即可。

//JavaScript

var user = new User(123);
user.set("name","Wolfgang");

//html

<input type="number" data-bind-123="name" /> 

input字段的值会自动反映出user对象的name属性,反之亦然。任务完成了!

不使用jQuery来创建数据双向绑定

在入如今的大多数项目中,都可能已经用到了jQuery,因此完全可以借用前面的例子。但是如果我们更进一步,移除对jQuery的依赖会怎样呢?事实上,这并不是太困难(尤其是当我们限定只支持IE8以上的版本)。最终,我们需要使用原生的JavaScript来实现一个自定义的PubSub以及观察DOM事件。

function DataBinder(object_id){
 //创建一个简单地PubSub对象 

 var pubSub = {
  callbacks: {}.

  on: function(msg,calssback){
   this.callbacks[msg] = this.callbacks[msg] || [];
   this.callbacks[msg].push(callback);
  },

  publish: function(msg){
   this.callbacks[msg] = this.callbacks[msg] || [];
   for(var i = 0, len = this.callbacks[msg].length; i<lenli++){
    this.callbacks[msg][i].apply(this,arguments);
   }
  }
 },

 data_attr = "data-bind-" + object_id,
 message = object_id + ":change",

 changeHandler = function(evt){
  var target = evt.target || evt.srcElemnt, //IE8兼容
   prop_name = target.getAttribute(data_attr);

   if(prop_name && prop_name !== ""){
    pubSub.publish(message,prop_name,target.value);
   }
 };

 //监听变化事件并代理到PubSub 
 if(document.addEventListener){
  document.addEventListener("change",changeHandler,false);
 }else{
  //IE8使用attachEvent而不是addEventListener  
  document.attachEvent("onchange",changeHandler);
 }

 //PubSub将变化传播到所有绑定元素 

 pubSub.on(message,function(vet,prop_name,new)_val){
  var elements = document.querySelectorAll("[" + data_attr + "=" + prop_name + "]"),
    tah_name;

  for(var i = 0,len =elements.length; i < len; i++){
   tag_name = elements[i].tagName.toLowerCase();

   if(tag_name === "input" || tag_name === "textarea" || tag_name === "select"){
   elements[i].value = new_val;
   }else{
    elements[i].innerHTML = new_val;
   }
  }
 });

 return pubSub;
}

模型可以和勤勉你的例子保持一直,除了在设置器中调用那个jQuery的trigger方法之外,它需要通过调用一个自定义的PubSub的publish方法来实现:

//在model的设置器中 

function User(uid){
//...

user = {
//...
set: function(attr_name,val){
 this.attribute[attr_name] = val;
 //使用“publish”方法 
 binder.publish(uid+ ":change", attr_name, val,this);
  }
 }

 //...
}  

再一次,我们使用原生的JavaScript代码实现了相同的结果,而不是使用臃肿的JavaScript框架。

本文译自easy two way data-binding in JavaScript,原文地址http://www.lucaongaro.eu/blog/2012/12/02/easy-two-way-data-binding-in-javascript/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

推荐内容

IntelliJ IDEA 注册码(激活到2089年)

idea2020注册激活码(激活到2100年)

实例分析Java实现的zip压缩及解压缩工具类

python3 pandas 如何读取MySQL数据和插入

ThinkPHP3.2.3框架如何实现分页功能

展开 +

收起 -

JavaScript 相关电子书
学习笔记
网友NO.296240

vue.js的双向数据绑定Object.defineProperty方法的神奇之处

vue.js 2.0版的双向数据绑定就是通过Object.defineProperty方法实现的,俗称属性拦截器。 这么说吧,vue.js是通过它实现双向绑定的。俗称属性拦截器。而且专门用来监控对象属性变化的Object.observe方法也被草案发起人撤回了(此方法在node环境中仍能使用)。可见defineProperty的威力之大。 Object.defineProperty() 不支持ie8 方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。 // 语法: /* * Object.defineProperty(obj,prop,descriptor) * @param: obj:需要定义属性的对象; * prop:需要定义或修改的属性; * descriptor:将被定义或修改属性的描述符{} * 返回值 : 返回传入函数的对象,即第一个参数obj */ 对象里目前存在的属性描述符主要有两种形式: 数据描述符和存取描述符. 数据描述符: 拥有可写或不可写值的属性* 可选键值: configurable: 当且仅当config……

网友NO.880834

vue.js使用v-model实现表单元素(input) 双向数据绑定功能示例

本文实例讲述了vue.js使用v-model实现表单元素(input) 双向数据绑定功能。分享给大家供大家参考,具体如下: v-model 一般表单元素(input) 双向数据绑定 el:'#box', //这里放的是选择器。 不然会不生效 !DOCTYPE htmlhtml lang="en"head meta charset="UTF-8" titlewww.jb51.net vue.js数据双向绑定/title style /style script src="https://cdn.bootcss.com/vue/2.4.4/vue.min.js"/script script window.onload=function(){ new Vue({ el:'#box',//这里放的是选择器 data:{ msg:'welcome vue' } }); }; /script/headbody div id="box" input type="text" v-model="msg" br {{msg}} /div/body/html 运行效果: 感兴趣的朋友可以使用 在线HTML/CSS/JavaScript代码运行工具 :http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。 希望本文所述对大家vue.js程序设计有所帮助。 ……

网友NO.772105

Avalonjs双向数据绑定与监听的实例代码

废话不多说了,直接给大家贴代码了,具体代码如下所示: div class="content_table" ms-controller="checkname" table thead tr th width="15%"提交核名/th th width="85%"请提供您打算使用的3个公司名称,我们将帮您注册并向登记机关提交您的核名信息。/th /tr /thead tbody tr td colspan="2" p class="or"看我的公司名是否已被占用/p a class="refer"立即查询/a /td /tr tr td colspan="2" p class="matter" label span行政区域:/span select name="" id="selArea" class="select_t" :duplex="@AdministrativeRegions" option value="天津市"天津市/option /select /label /p form action="" id="c_name" p class="matter" label span字号:/span input class="thing thing_nn" type="text" placeholder="云信" name='c_name' ms-duplex="@FiledOne"br input class="thing thing_nn thing_add" type="text" name='s_name' placeholder="请输入第二个公司名称" ms-duplex="@FiledTwo"br input class="thing thing_nn thing_add" type="text" name='t_name'……

网友NO.219653

Vue.js实现双向数据绑定方法(表单自动赋值、表单自动取值)

1、使用Vue.js实现双向表单数据绑定,例子 !--html代码--!DOCTYPE htmlhtmlheadmeta charset="utf-8"meta http-equiv="X-UA-Compatible" content="IE=edge"title财产查勘处理/titlelink rel="stylesheet" type="text/css" href="../css/global.css" rel="external nofollow" /link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css" rel="external nofollow" /link rel="stylesheet" type="text/css" href="../css/AdminLTE.min.css" rel="external nofollow" /link rel="stylesheet" type="text/css" href="../css/propertySurvey.css" rel="external nofollow" //headbody div class="container-fluid" div 请输入物损查看信息/div h4 class="box-title" i class="glyphicon glyphicon-play-circle" /i 报案信息 /h4 hr / div class="row text-center" div label损失方/labelinput v-model="RegistInfo_name" type="text" name="RegistInfo_name"/ /div div label联系人/labelinput v-model="RegistInfo_user" type="text" name="RegistInfo_user"/ /div div label联系方式/label input v-model="RegistIn……

<
1
>

电子书 编程教程 文档 软件 源码 视频

Copyright 2018-2020 xz577.com 码农之家

本站所有电子书资源不再提供下载地址,只分享来路

免责声明:网站所有作品均由会员网上搜集共同更新,仅供读者预览及学习交流使用,下载后请24小时内删除

版权投诉 / 书籍推广 / 赞助:QQ:520161757