双向数据绑定是指改变绑定的对象的属性在用户界面上的变化的能力,反之亦然。换句话说,如果我们有一个用户对象的名称属性,一旦我们将新值赋给user.name,新名称将显示在用户界面。同样,如果用户界面包含一个输入框,输入用户的名字,一个新的输入值应使名称属性的用户对象的相应变化。

许多流行的js框架等客户ember.js,Angular.js,或knockoutjs所有发布双向数据绑定的最新特点。这并不意味着它是很难实现从零或是使用这些框架的唯一选择时,这些功能是必要的。下面的想法其实是很基本的,可考虑一个3步计划:

我们需要一种将UI元素和属性绑定到一起的方法。

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

我们需要让所有绑定对象和元素知道变化。

有很多方法可以实现以上的想法,并且有一个简单而有效的方式来使用PubSub模式。这个想法很简单:我们使用的数据的特点,结合HTML代码,和所有的Javascript对象和DOM元素结合在一起,将订阅一个PubSub的对象。只要一个Javascript对象或一个HTML输入元素听数据的改变,这将触发必然PubSub对象的事件,所以其他绑定对象和元素将做出相应的变化。

用jQuery做一个简单的实现

对于DOM事件的订阅和发布,用jQuery实现非常简单,然后我们使用jQuery,如下所示:


函数的DataBinder(object_id){
使用jQuery对象简单 / / PubSub
VaR PubSub = jQuery({ });
我们期望一个'数据'元素指定/绑定。
表单:数据绑定在
无功data_attr =绑定+ object_id,
消息= object_id +:改变;
使用元素绑定属性和代理来监听元素上的更改事件
到 / /他们PubSub这样的变化是广播到所有连接的对象
jQuery(文档)
输入= jQuery(此);
PubSub.trigger(消息,{ $ input.data(data_attr),input.val美元()}));
});
更改传播到所有绑定/ PubSub的元素,设定值
输入标签或HTML内容的其他标签
PubSub.on(信息、功能(EVT,prop_name,new_val){
jQuery({数据+ data_attr +=+ prop_name +})。每个(函数(){)
绑定$ = jQuery(此);
如果($ bound.is(输入文本,选择)){
bound.val美元(new_val);
{人}
bound.html美元(new_val);
}
});
});
返回PubSub;
}


对于上述实现,以下是实现用户模型的最简单方法:


功能的用户(UID){
VaR粘结剂=新DataBinder(UID),
用户{ {
属性:{ },
属性setter发布变更使用 / DataBinder PubSub
设置:功能(attr_name,Val){
这个属性{ attr_name } = val;
Binder.trigger (uid + : change
},
得到:功能(attr_name){
返回此属性attr_name } {;
},
_binder:粘合剂
};
在PubSub / /订阅
Binder.on(UID +:变化
如果(启动器)!=用户){
User.set(attr_name,new_val);
}
});
返回用户;
}


现在,如果我们想将用户模型属性绑定到UI,我们只需要将相应的数据属性绑定到相应的HTML元素。



var用户=新用户(123);
user.set(名




这个输入值自动映射到用户对象的name属性,反之亦然。



此外,这个简单的实现将完成!

不需要jQuery实现



在今天的大多数项目中,jQuery可能已经被使用过,所以上面的例子是完全可以接受的,但是如果我们需要把它做到另一个极端并删除jQuery的依赖性,我们该怎么做呢嗯,确认这不是很难(尤其是当我们限制IE 8或更高版本)。最后,我们要使用一个通用的Javascript实现自定义PubSub保持DOM事件:


函数的DataBinder(object_id){
一个简单的对象 / /创建PubSub
VaR PubSub = { {
回调:{ },
函数(MSG,回调){
这个回调{味精=这个回调{ { } } } | |味精;
这个回调{味精}推(回调);
},
发布:函数(MSG){
这个回调{味精=这个回调{ { } } } | |味精
对于(var i =,len =这个回调{味精}。长度;我< len;i++){
这个回调{味精,我}。应用(这观点);
}
}
},
data_attr =数据绑定+ object_id,
消息= object_id +:变化
changehandler =功能(EVT){
VaR目标= evt.target evt.srcelement / IE兼容性| |。
prop_name = target.getattribute(data_attr);
如果(prop_name prop_name = ={!)
PubSub.publish(消息,prop_name,目标值);
}
};
听变化事件和代理 / PubSub
如果(文件。addEventListener){
Document.addEventListener(变化
{人}
使用attachevent代替addEventListener / / IE
document.attachevent(变化
}
PubSub的更改传播到所有绑定 / /元素
PubSub.on(信息、功能(EVT,prop_name,new_val){
var elements = document.queryselectorall({+ data_attr +=+ prop_name +})
tag_name;
对于(var i =,len = elements.length;我< len;i++){
tag_name =元素{我}。tagname.tolowercase();
如果(tag_name = = = = = =输入| | tag_name文本| | tag_name = 选择){
元素{我}。值= new_val;
{人}
元素的innerHTML = new_val {我};
}
}
});
返回PubSub;
}


除了触发方法调用setter jQuery,模型可以是相同的。调用触发方法将取代发布方法,调用我们的不同特点定制PubSub:


模型的设置程序:
功能的用户(UID){
…
用户{ {
…
设置:功能(attr_name,Val){
这个属性{ attr_name } = val;
发布方法使用
Binder.publish(UID +:变化
}
}
…
}


我们再次通过不可用的一百行完成我们想要的结果,并且我们可以保持一个纯Javascript。

以上是关于js双向数据绑定的相关教程,希望对大家有所帮助。