jQuery的观察者模式?什么玩意,刚开始听到这个专业术语,有点懵逼,进一步了解后恍然大悟,我们平时经常碰到,只不过没有去真正了解这个专业定义而已,OK,童鞋们一起来学习下吧。
观察者模式的定义
观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。
理解观察者模式
观察者模式 (pub/sub) 的背后,总的想法是在应用程序中增强松耦合性。并非是在其它对象的方法上的单个对象调用。一个对象作为特定任务或是另一对象的活动的观察者,并且在这个任务或活动发生时,通知观察者。观察者也被叫作订阅者(Subscriber),它指向被观察的对象,既被观察者(Publisher 或 subject)。当事件发生时,被观察者(Publisher)就会通知观察者(subscriber)。
观察者模式的好处
1、支持简单的广播通信,自动通知所有已经订阅过的对象。
2、页面载入后目标对象很容易与观察者存在一种动态关联,增加了灵活性。
3、目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。
观察者的使用场合
观察者的使用场合就是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。先看官网的demo这个例子,涉及到了 add 与 fire方法,熟悉设计模式的童鞋呢,一眼就能看出,其实又是基于发布订阅(Publish/Subscribe)的观察者模式的设计。
体验jQuery中的观察者模式
在jQuery中,on方法可以为元素绑定事件,trigger方法可以手动触发事件,围绕这2个方法,我们来体验jQuery中的观察者模式。
on方法绑定内置事件,自然触发
比如,我们给页面的body元素绑定一个click事件,这样写。
<!doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <script src="/demo/js/jq.js"></script> <script type="text/javascript"> $(function() { $('body').on('click', function () { console.log('被点击了~~'); }); }); </script> </head> <body> <h1>hello</h1> </body> </html>
以上,我们只有点击body,才能触发click事件。也就是说,当给页面元素绑定内置事件后,事件的触发是在内置事件发生的那刻。
on方法绑定内置事件,手动触发
使用trigger方法,也可以手动触发元素绑定的内置事件。
<script type="text/javascript"> $(function() { $('body').on('click', function () { console.log('被点击了~~'); }); $('body').trigger('click'); }); </script>
以上,无需点击body,在页面加载完毕,body自动触发了click事件
on方法绑定自定义事件,手动触发
我们知道,click是jquery内置的事件,那么,是否可以自定义事件,并手动触发呢?
<script type="text/javascript"> $(function() { $('body').on('someclick', function () { console.log('被点击了~~'); }); $('body').trigger('someclick'); }); </script>以上,我们自定义了一个someclick事件,得到的结果和上面一样。
于是,我们发现:我们可以为元素绑定自定义事件,并且用trigger方法触发该事件。
当然,自定义事件的名称可以按照"命名空间.自定义事件名称"的形式来写,比如app.someclick,这在大型项目中尤其有用,这样可以有效避免自定义事件名称冲突。
如果从"发布订阅"这个角度来看,on方法相当于订阅者、观察者,trigger方法相当于发布者
从"异步获取json数据"来体验jQuery观察者模式
在根目录下,有一个data.json的文件。
{ "one" : "Hello", "two" : "World" }
现在,通过异步的方式来获取json数据。看下代码:
<script type="text/javascript"> $(function () { $.getJSON('data.json', function(data) { console.log(data); }); }); </script>
如果用一个全局变量来接收异步获取的json数据。
<script type="text/javascript"> $(function () { var data; $.getJSON('data.json', function(results) { data = results; }); console.log(data); }); </script>
这次,我们得到的结果却是undefined,这是为什么?
--因为,当$.getJSON方法还在获取数据的时候,就已经执行console.log(data),而此时data还没有数据。
如何解决这个问题呢?
--如果在$.getJSON方法之外先定义好需要执行的方法,然后在$.getJSON方法的回调函数里真正触发这个方法,不就解决了吗?看下代码:
<script type="text/javascript"> $(function () { $.getJSON('data.json', function(results) { $(document).trigger('app.myevent', results); //相当于发布 }); $(document).on('app.myevent', function(e, results) { //相当于订阅 console.log(results); }); }); </script>
以上,on方法就像一个订阅者,它订阅了自定义事件app.myevent;而trigger方法就像一个发布者,它发布事件和参数后,才真正让订阅者方法得以执行
jQuery观察者模式的扩展方法
为此,我们还可以为jQuery观察者模式专门写一个扩展方法。
<script type="text/javascript"> $(function () { $.getJSON('data.json', function (results) { $.publish('app.myevent', results); }); $.subscribe('app.myevent', function(e, results) { console.log(results); }); }); (function($) { var o = $({});//自定义事件对象 $.each({ trigger: 'publish', on: 'subscribe', off: 'unsubscribe' }, function(key, val) { jQuery[val] = function() { o[key].apply(o, arguments); }; }); })(jQuery); </script>
以上,定义了全局的publish和subscribe方法,我们在任何时候都可以调用。来段代码:
<script type="text/javascript"> $(function () { $.getJSON('data.json', function (results) { $.publish('app.myevent', results); }); $.subscribe('app.myevent', function(e, results) { $('body').html( results.one ); }); });
总结
了解完后,有木有发现观察者模式也就那么一回事,不难理解,其实我们上面提到的jQuery的观察者模式,实际上是让on方法绑定的自定义事件先不执行,直到使用trigger方法来触发事件。使用jQuery的观察者模式的好处是:一次发布,多次订阅。
当然还有其他形式,这里不可能全部分享,通过本次的引导,希望让你有进一步学习的冲动,加油↖(^ω^)↗。
网友评论文明上网理性发言 已有0人参与
发表评论: