我一直在互联网上寻找在jquery中实现观察者模式的例子。
我想要这样的。
observer1.observe(subject);
observer2.observe(subject);为观察者定义一些自定义事件回调
observer1.bind('customEvent', function(contextData) {
//Some code
});
observer1.bind('anotherCustomEvent', function(contextData) {
//Some code
});
observer2.bind('customEvent', function(contextData) {
//Some code
});下面的代码行将触发两个观察者的customEvent回调
subject.trigger('customEvent', contextData);而下面的代码将仅在observer1上触发anotherCustomEvent,因为observer2没有绑定该自定义事件
subject.trigger('anotherCustomEvent', contextData);互联网上的指南更一般:
$( document ).on( "topicName" , function () {
//..perform some behaviour
});
$( document ).trigger( "topicName" );(来自http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjquery的示例)我不明白如何使用上面的代码来实现我正在寻找的东西。
要么我必须像这样(如果我像上面的例子一样保持它):
$(document).on("customEvent", function () {
observer1.trigger("customEvent");
observer2.trigger("customEvent");
});
$(subject).click(function() {
$(document).trigger("customEvent");
});或者更好一点:
$(subject).click(function() {
observer1.trigger("customEvent");
observer2.trigger("customEvent");
});无论哪种方式,我都不得不编辑主题-click-callback或document-customEvent-callback,而不是告诉观察者订阅主题。
我是否误解了观察者模式,或者有什么方法可以实现我想要的吗?
http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript在本章后面提到了发布/订阅模式。对我来说,这可能是一种方法,但我遗漏了示例背后的代码。
发布于 2012-09-26 21:29:14
从你的评论中:
我不明白这是怎么实现的,因为你必须告诉主题哪些元素要由选择器触发,而不是让主题有一个观察者可以注册到的列表
如果我错了,请纠正我,但您似乎误解了该模式是如何在jQuery中实现的。你不会“告诉主题要触发哪些元素”,主题也没有“观察者可以注册的列表”。它是这样工作的:
例如,考虑以下HTML:
<div id="div1">div 1</div>
<div id="div2">div 2</div>让我们让内部div触发一个名为'custom'的自定义事件。你定义了什么时候应该发生,在这个例子中,当它们被点击时就会发生:
$('div').on('click', function(e) {
$(this).trigger('custom');
});现在让我们让document元素订阅那个自定义事件:
$(document).on('custom', function(e) {
console.log('document is handling custom event triggered by ' + e.target.id);
});当某个div触发自定义事件时,会通知观察者/订阅者,并将一条消息记录到控制台。
该示例使用document作为观察者的原因是:事件在DOM树上冒泡,并且只能由触发它的元素的祖先元素捕获。因为document是DOM树的根,所以它可以看到所有事件。如果#div1是我们的观察者,它将只看到由#div1本身触发的事件,而不会看到由#div2触发的事件。
也许这个限制就是让你困惑的地方?
有一些方法可以绕过这一限制,但通常情况下,如果您想根据#div2触发的事件对#div1执行某些操作,则只需在document元素(或两个div的最接近的共同祖先)上设置的回调中执行即可。无论如何,看起来你真的想要一个替代方案,所以这里有一个jQuery插件的形式:
$.fn.observe = function(eventName, callback) {
return this.each(function(){
var el = this;
$(document).on(eventName, function(){
callback.apply(el, arguments);
})
});
}你可以这样使用它:
$('#div1').observe('custom', function(e) {
// do something
});现场示例:http://jsfiddle.net/JwJsP/1
发布于 2012-09-26 06:02:13
可能不是你想要的,但是观察者可以订阅监听事件:
$(document).on('customEvent', '.iObserver', function() {
console.log('i am observer');
});
// add observer
$('ul li#Observer').addClass('iObserver');
//remove observer
$('ul li#Observer').removeClass('iObserver');发布于 2015-02-18 23:09:39
如果您仍在寻找使用jQuery的事件引擎的实现,您可以尝试以下代码:
//The implementation
(function($) {
var o = $({});
$.each({
trigger: 'publish',
on: 'subscribe',
off: 'unsubscribe'
}, function(key, val) {
jQuery[val] = function() {
o[key].apply(o, arguments);
};
});
})(jQuery);
// The way to use it is this:
var somedata = [1, 2, 3, 5, 4, 7, 8];
$.publish('myEvent', somedata); // with data
$.publish('myEvent'); // without data
$.subscribe('myEvent', function(event, data) {
// handle the event
});https://stackoverflow.com/questions/12590091
复制相似问题