I want to implement a custom event that can be "transmitted" rather than sent for specific purposes. Only those elements that have registered as listeners for such events will receive them.
What I mean will be as follows.
Firstly, in different places in the code there would be expressions of the form
some_subscriber.on_signal( 'some_signal', some_handler );
I use the term signal as a shorthand for a "broadcast event." In the above expression, some_subscriber registered as a listener of one type (called "some_signal") of such signals, providing a handler for it.
Elsewhere in the code would be expressions of the form
publisher.signal_types[ 'some_signal' ].broadcast( event_data );
When such requests are executed, a new event and "broadcast" are created. By this, I mean that the code that calls the broadcast method does not have direct information about the listeners for the signal it emits.
I implemented a sketch of this idea in this jsFiddle , mainly in order to illustrate what I described in the words above 1 . (This, of course, is not a production class, and I'm not sure that it can be done like this.)
The key elements of this implementation are as follows. Firstly, publisher objects do not track their subscribers, which can be seen when implementing the factory method for such a publisher, as shown below:
function make_publisher ( signal_types ) { // ... var _ , signal = {} , ping = function ( type ) { signal[ type ].broadcast( ... ); } ; signal_types.forEach( function ( type ) { signal[ type ] = $.register_signal_type( type ); } ); return { signal_types: signal_types, ping: ping }; }
This publisher object provides only two elements: the types of signals it passes (in signal_types ), and the ping method. When its ping method ping called, the publisher responds by sending a signal:
signal[ type ].broadcast( ... )
The final recipients of this broadcast are nowhere to be seen in this code.
Secondly, elsewhere in the code, subscribers are registered as listeners of these broadcast signals, for example
$( some_selector ).on_signal( signal_type, some_handler );
Note. . In principle, it is impossible to illustrate the rationale for this scheme using an example that is both small and realistic. The reason for this is because the strength of this scheme is that it maintains a very weak connection between the publisher code and the subscriber code, and this is a function that is never needed in a small example. In contrast, in a small example, code that implements such a loose connection invariably occurs as unnecessarily complex. Therefore, it is important to keep in mind that this seemingly excessive complexity is a context artifact. The loose coupling is very useful in large projects. In particular, free communication through the publisher / subscriber template is one of the main features of MVC.
My question is: is there a better (or at least a more standard) way to achieve this effect of "broadcasting" user events?
(I'm interested in both jQuery-based answers and "pure JS").
1 An early, ill-fated version of this message was greeted with an almost universal misunderstanding and (of course) a too typical downward vote. With one exception, all of the comments I received challenged the very premise of publication, and one directly questioned my understanding of the basics of event-driven programming, etc. I hope that by presenting a working example of what I mean, at least this will not work out as incredibly as it was when I described it only in words. Fortunately, one helpful comment I received on this earlier post told me about the jQuery.Callbacks function. This is really good advice; the sketch implementation mentioned in the post is based on jQuery.Callbacks .