记录下用jquery实现双向绑定的

来源:互联网 发布:编程软件利润率 编辑:程序博客网 时间:2024/05/06 18:56

首先复习下javascript对象的创建方法,一共有3种,分别是:

1,使用内置对象

例如,var obj= new String("aaa");

2,使用json

例如,var obj = {};

3,自定义对象

例如,function obj{this.name="aaa";this.text=function(){alert("aaa")}}

var obj= new obj();

然后把javascript对象转换成jquery对象方法就是var jquery = $(obj);


双向绑定用到了观察者模式,首先介绍下什么是观察者模式

观察者模式又叫做发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察着对象。它是由两类对象组成,主题和观察者,主题负责发布事件,同时观察者通过订阅这些事件来观察该主体,发布者和订阅者是完全解耦的,彼此不知道对方的存在,两者仅仅共享一个自定义事件的名称。


理解观察者模式:


JS传统事件就是一个观察者模式,之所以要有观察者模式,是因为有时候和传统事件无关的事件,比如:2个或者更多模块的直接通信问题,比如说我有个index.html页面,我有很多JS文件,比如:


a.js: function a(){};    b.js: function b(){};  c.js  function c(){};  等等。后面还有许多这样的JS, 那么我要在index.html初始化这些函数的话,我需要这样调用a();b();c()等等,也就是说页面调用的时候 我要这样调用,增加了依赖性,我要知道有多少个函数要这样初始化调用,但是如果我们现在用观察者模式就不需要知道有哪些订阅者,比如一个模块(或者多个模块)订阅了一个主题(或者事件),另一个模块发布这个主题时候,订阅这个主题模块就可以执行了,观察者主要让订阅者与发布者解耦,发布者不需要知道哪些模块订阅了这个主题,它只管发布这个主题就可以了,同样订阅者也无需知道那个模块会发布这个主题,它只管订阅这个主题就可以了。这样2个模块(或更多模块)就实现了关联了。而不需要和上面代码一样,我要知道哪些模块要初始化,我要怎样初始化。这只是一个简单的列子解释观察者模式要使用在什么地方,我也看过很多博客关于这方面的资料,但是很多人写博客只是讲了如何实现观察者模式及观察者模式的好处,并没有讲我们什么时候该使用观察者模式,所以我列举了上面的列子,就是多个不同业务模块需要相互关联的时候,可以使用观察者模式。就好比requireJS,seaJS,KISSY解决依赖的问题一样(比如A依赖于B,B依赖于C,只要一个解决入口文件,其他都会异步加载出来一样)。也就是说各个模块之间的关联性可以使用观察者模式来设计。

这种模式有多种实现,比如jquery插件 pub/sub


这里我不用插件直接用jquery的tirgger方法来发布,用on方法来订阅

$(selector).trigger(event,[param1,param2,...])

jQueryObject.on( events [, selector ] [, data ], handler )


<%@ page language="java" import="java.util.*"contentType="text/html; charset=utf-8"%><html><script src="jquery.js"></script><script type="text/javascript">var jsonObj = {};//发布消息function doTest() {$(jsonObj).trigger("test", [ "aaa", "bbb" ]);}//程序初始化的时候就订阅消息$(jsonObj).on("test", function(e, para1, para2) {alert(para1)});</script><body><input type="button" onclick="doTest()" value="测试发布订阅模式"></body></html>


OK,这个发布订阅模式明白了再看下面这个用jquery实现的双向绑定的代码就会简单一些了。

下面这段代码最后的button是用来测试修改model也会更改UI的。

<%@ page language="java" import="java.util.*"contentType="text/html; charset=utf-8"%><html><script src="jquery.js"></script><script type="text/javascript">function DataBinder(object_id) {// Use a jQuery object as simple PubSubvar pubSub = jQuery({});// We expect a `data` element specifying the binding// in the form:data-bind-<object_id>="<property_name>"var data_attr = "bind-" + object_id, message = object_id + ":change";// Listen to chagne events on elements with data-binding attribute and proxy// then to the PubSub, so that the change is "broadcasted" to all connected objectsjQuery(document).on("change","[data-" + data_attr + "]",function(eve) {var $input = jQuery(this);pubSub.trigger(message, [ $input.data(data_attr),$input.val() ]);});// PubSub propagates chagnes to all bound elemetns,setting value of// input tags or HTML content of other tagspubSub.on(message, function(evt, prop_name, new_val) {jQuery("[data-" + data_attr + "=" + prop_name + "]").each(function() {var $bound = jQuery(this);if ($bound.is("input,textarea,select")) {$bound.val(new_val);} else {$bound.html(new_val);}});});return pubSub;}function User(uid) {var binder = new DataBinder(uid),user = {attributes : {},// The attribute setter publish changes using the DataBinder PubSubset : function(attr_name, val) {this.attributes[attr_name] = val;binder.trigger(uid + ":change", [ attr_name, val, this ]);},get : function(attr_name) {return this.attributes[attr_name];},_binder : binder};// Subscribe to PubSubbinder.on(uid + ":change",function(evt, attr_name, new_val, initiator) {if (initiator !== user) {user.set(attr_name, new_val);}});return user;}var user = new User(123);user.set("name", "999");function setNewVal(val) {user.set("name", $("#newVal").val());}</script><body><h2>Hello World!</h2><input type="text" data-bind-123="name" /><br /><br /><br /><input type="button" value="修改value的值 " onclick="setNewVal()"><input type="text" id="newVal" /></body></html>

最后忘了说双向绑定的概念了

双向数据绑定指的是当对象的属性发生变化时能够同时改变对应的UI,反之亦然。换句话说,如果我们有一个user对象,这个对象有一个name属性,无论何时你对user.name设置了一个新值,UI也会展示这个新的值。同样的,如果UI包含一个用于数据用户名字的输入框,输入一个新值也会导致user对象的name属性发生相应的改变。

应用场景:

双向数据绑定最经常的应用场景就是表单了,这样当用户在前端页面完成输入后,不用任何操作,我们就已经拿到了用户的数据存放到数据模型中了。



0 0
原创粉丝点击