双向数据绑定指的是将对象属性变化绑定到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); } })}
新闻热点
疑难解答
图片精选