我一直在互联网上寻找在 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 没有绑定(bind)该自定义事件
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");
});
无论哪种方式,我都不得不编辑 subject-click-callback 或 document-customEvent-callback,而不是告诉观察者订阅主题。
我是不是误解了观察者模式,或者有没有办法实现我正在寻找的东西?
http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript在该章的后面提到发布/订阅模式。这对我来说可能是一种方式,但我缺少示例背后的代码。
最佳答案
来自您的评论:
I just can't see how this is achieved when you have to tell the subject which elements to trigger by selectors instead of the subject having a list that the observer can register to
如果我错了请纠正我,但您似乎误解了该模式是如何在 jQuery 中实现的。您不会“告诉主题触发哪些元素”,主题也没有“观察者可以注册的列表”。它是这样工作的:
- 主题/发布者发出/触发某些事件(在您定义的某些情况下)。
- 观察者/订阅者监听某些事件。它保留它订阅的事件列表。
- 这都是基于 DOM 事件的,因此受到 DOM 事件模型的限制。
例如,考虑以下 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
});
关于javascript - Jquery 观察者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12590091/