Javascript Jquery观察者模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12590091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jquery Observer pattern
提问by Anders
I've been looking over the internet for examples of implementing the observer pattern in jquery.
我一直在互联网上寻找在 jquery 中实现观察者模式的例子。
I would like to have it like this
我想要这样
observer1.observe(subject);
observer2.observe(subject);
Define some custom event callbacks for the observers
为观察者定义一些自定义事件回调
observer1.bind('customEvent', function(contextData) {
//Some code
});
observer1.bind('anotherCustomEvent', function(contextData) {
//Some code
});
observer2.bind('customEvent', function(contextData) {
//Some code
});
The following line would then trigger the customEvent callbacks of both observers
以下行将触发两个观察者的 customEvent 回调
subject.trigger('customEvent', contextData);
while the following would fire anotherCustomEvent on observer1 only, since observer2 doesn't have that custom event binded
而以下只会在观察者 1 上触发 anotherCustomEvent,因为观察者 2 没有绑定该自定义事件
subject.trigger('anotherCustomEvent', contextData);
Guides on the internet is more general:
互联网上的指南更一般:
$( document ).on( "topicName" , function () {
//..perform some behaviour
});
$( document ).trigger( "topicName" );
(Example from http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjquery) I can't see how the above code can be used to accomplish what I'm looking for.
(来自http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjquery 的示例)我看不出如何使用上面的代码来完成我正在寻找的内容。
Either i would have to make it like this (if I keep it like the above example):
要么我必须这样做(如果我像上面的例子一样保持它):
$(document).on("customEvent", function () {
observer1.trigger("customEvent");
observer2.trigger("customEvent");
});
$(subject).click(function() {
$(document).trigger("customEvent");
});
or a little bit better:
或者更好一点:
$(subject).click(function() {
observer1.trigger("customEvent");
observer2.trigger("customEvent");
});
Either way I'm stuck with having to edit the subject-click-callback or document-customEvent-callback instead of telling the observer to subscribe to the subject.
无论哪种方式,我都不得不编辑 subject-click-callback 或 document-customEvent-callback,而不是告诉观察者订阅主题。
Have I misunderstood observer pattern or is there a way to achieve what I'm looking for?
我误解了观察者模式还是有办法实现我正在寻找的?
http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascriptmention Publish/Subscribe Pattern a bit further down in that chapter. That could be a way for me, but I'm missing the code behind the example.
http://addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjavascript提到发布/订阅模式在该章节的更深处。这对我来说可能是一种方式,但我错过了示例背后的代码。
回答by bfavaretto
From your comment:
从你的评论:
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
当您必须告诉主体选择器触发哪些元素而不是主体具有观察者可以注册的列表时,我只是看不出这是如何实现的
Please correct me if I'm wrong, but you seem to be misunderstanding how the pattern was implemented in jQuery. You don't "tell the subject which elements to trigger", and the subject doesn't have "a list that the observer can register to" either. It works like this:
如果我错了,请纠正我,但您似乎误解了该模式是如何在 jQuery 中实现的。您不会“告诉主题要触发哪些元素”,主题也没有“观察者可以注册到的列表”。它是这样工作的:
- The subject/publisher emits/triggers certain events (on certain circumstances you define).
- The observer/subscriber listens to certain events. It keeps a list of the events it subscribed to.
- That's all based on DOM events, so it's limited by the DOM Event Model.
- 主题/发布者发出/触发某些事件(在您定义的某些情况下)。
- 观察者/订阅者监听某些事件。它保留了它订阅的事件列表。
- 这都是基于DOM事件的,所以受DOM事件模型的限制。
For example, consider the following HTML:
例如,考虑以下 HTML:
<div id="div1">div 1</div>
<div id="div2">div 2</div>
Let's make the inner divs trigger a custom event called 'custom'
. You define when that should happen, on this example this will happen when they are clicked:
让我们让内部 div 触发一个名为'custom'
. 你定义什么时候应该发生,在这个例子中,这将在点击它们时发生:
$('div').on('click', function(e) {
$(this).trigger('custom');
});
Now let's make the document
element subscribe to that custom event:
现在让我们让document
元素订阅该自定义事件:
$(document).on('custom', function(e) {
console.log('document is handling custom event triggered by ' + e.target.id);
});
When the custom event is triggered by one of the divs, the observer/subscriber is notified and a message is logged to the console.
当自定义事件由其中一个 div 触发时,观察者/订阅者会收到通知,并将一条消息记录到控制台。
The example uses document
as the observer for a reason: events bubble up the DOM tree, and can only be caught by elements that are ancestors of the one that triggered it. Since document
is the root of the DOM tree, it can see all events. If #div1
was our observer, it would only see events triggered by #div1
itself, but not the ones triggered by #div2
.
该示例document
用作观察者的原因是:事件在 DOM 树中冒泡,并且只能被触发它的元素的祖先元素捕获。由于document
是 DOM 树的根,它可以看到所有事件。如果#div1
是我们的观察者,它只会看到由#div1
它自己触发的事件,而不会看到由#div2
.
Maybe that limitation is what confused you?
也许这个限制让你感到困惑?
There are ways to circumvent that limitation, but usually, if you want to do something to #div1
based upon an event triggered by #div2
, you just do it from the callback you have setup on the document
element (or the closest common ancestor to both divs). Anyway, it seems you really want an alternative, so here is one in the form of a jQuery plugin:
有很多方法可以绕过这个限制,但通常,如果你想#div1
根据由 触发的事件做一些事情#div2
,你只需从你在document
元素上设置的回调(或最接近两个 div 的共同祖先)来做。无论如何,您似乎真的想要一个替代方案,所以这里有一个 jQuery 插件形式的:
$.fn.observe = function(eventName, callback) {
return this.each(function(){
var el = this;
$(document).on(eventName, function(){
callback.apply(el, arguments);
})
});
}
You can use it like this:
你可以这样使用它:
$('#div1').observe('custom', function(e) {
// do something
});
Live example: http://jsfiddle.net/JwJsP/1
现场示例:http: //jsfiddle.net/JwJsP/1
回答by Felix
Might be not what you are looking for, however observers can subscribe for listening events:
可能不是你想要的,但是观察者可以订阅监听事件:
$(document).on('customEvent', '.iObserver', function() {
console.log('i am observer');
});
// add observer
$('ul li#Observer').addClass('iObserver');
//remove observer
$('ul li#Observer').removeClass('iObserver');
回答by sabotero
If you're still looking for some implementation using the events engine of jQuery you can try this code:
如果您仍在寻找使用 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
});