双向数据绑定指的是将对象属性变化绑定到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/
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# js
# 数据绑定
# vue.js数据绑定的方法(单向、双向和一次性绑定)
# 实现非常简单的js双向数据绑定
# javascript实现数据双向绑定的三种方式小结
# 轻松实现javascript数据双向绑定
# JS原生数据双向绑定实现代码
# JS数据双向绑定原理与用法实例分析
# js实现视图和数据双向绑定的方法分析
# js项目中双向数据绑定的简单实现方法
# 绑定
# 自定义
# 当我们
# 来实现
# 都将
# 这并
# 自己的
# 而不是
# 器中
# 也会
# 在这个
# 尤其是
# 有很多
# 什么时候
# 只需
# 要在
# 很简单
# 它可以
# 可以使用
# 想把
相关文章:
天津个人网站制作公司,天津网约车驾驶员从业资格证官网?
如何续费美橙建站之星域名及服务?
如何彻底卸载建站之星软件?
如何用低价快速搭建高质量网站?
如何快速建站并高效导出源代码?
,sp开头的版面叫什么?
建站主机选购指南:核心配置与性价比推荐解析
建站主机助手选型指南:2025年热门推荐与高效部署技巧
建站之星Pro快速搭建教程:模板选择与功能配置指南
如何选择可靠的免备案建站服务器?
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
广州营销型建站服务商推荐:技术优势与SEO优化解析
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
网站制作员失业,怎样查看自己网站的注册者?
沈阳制作网站公司排名,沈阳装饰协会官方网站?
如何选择域名并搭建高效网站?
如何快速搭建个人网站并优化SEO?
高性价比服务器租赁——企业级配置与24小时运维服务
无锡营销型网站制作公司,无锡网选车牌流程?
建站之星多图banner生成与模板自定义指南
电影网站制作价格表,那些提供免费电影的网站,他们是怎么盈利的?
公众号网站制作网页,微信公众号怎么制作?
大连网站设计制作招聘信息,大连投诉网站有哪些?
宿州网站制作公司兴策,安徽省低保查询网站?
建站之星2.7模板快速切换与批量管理功能操作指南
网站制作价目表怎么做,珍爱网婚介费用多少?
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
建站之星后台管理如何实现高效配置?
b2c电商网站制作流程,b2c水平综合的电商平台?
山东网站制作公司有哪些,山东大源集团官网?
宝塔新建站点为何无法访问?如何排查?
英语简历制作免费网站推荐,如何将简历翻译成英文?
设计网站制作公司有哪些,制作网页教程?
如何在阿里云服务器自主搭建网站?
义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?
如何正确下载安装西数主机建站助手?
如何在七牛云存储上搭建网站并设置自定义域名?
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
如何在橙子建站中快速调整背景颜色?
道歉网站制作流程,世纪佳缘致歉小吴事件,相亲网站身份信息伪造该如何稽查?
如何快速搭建高效WAP手机网站吸引移动用户?
如何通过cPanel快速搭建网站?
建站VPS配置与SEO优化指南:关键词排名提升策略
如何注册花生壳免费域名并搭建个人网站?
高端建站如何打造兼具美学与转化的品牌官网?
移民网站制作流程,怎么看加拿大移民官网?
如何用搬瓦工VPS快速搭建个人网站?
php条件判断怎么写_ifelse和switchcase的使用区别【对比】
香港服务器部署网站为何提示未备案?
*请认真填写需求信息,我们会在24小时内与您取得联系。