Reputation: 1876
I'm trying to listen for a custom event but I would like to effectively 'ignore' the fact that it's namespaced or somehow listen to all namespaces without defining them individually.
$('#test').on('custom', ...);
$('#test').trigger('custom.namespace1');
$('#test').trigger('custom.namespace2');
The reason I want to be able to do this is because I have multiple ui plugins that fire events when they are hidden/shown. These events are mainly used internally but are namespaced so they don't collide with each other. However I would also just like to know when a particular ui element is hidden, independent of its source to perform other cleanup logic.
In the above example, nothing will happen because the trigger events are namespaced. Can I listen to all namespaces with something to the effect of custom.*
?
Fiddle demonstrating the problem.
Thanks
Edit
Even something like this would be desirable but still can't get it to work
$('#test').on('custom.global', log);
$('#test').trigger('custom.global.namespace1');
$('#test').trigger('custom.global.namespace2');
Upvotes: 7
Views: 1610
Reputation: 4387
I just ran into this and here's my solution. Javascript is a fun language and events are just strings. Why not define your events beforehand and just dynamically add them to an "all" event? No need to worry about getting out of sync.
You could extend this however you want. When a widget is registered, have it register itself and append it to the list. Use an array and just do myEvents.join(" ")
to generate all of them. On app bootstrap, do what I do below and add all keys in an object to an "all" event. Whatever you want to do is fine.
PS. The "Vent" example I use is from: https://github.com/reedspool/jquery-event-aggregator/blob/master/eventAggregator.jquery.js
var stand_in = {},
$stan = $(stand_in),
// Don't give Stan to anyone else, he's precious
$empty = $(),
trigger = function(name, ...args) {
$stan.trigger.apply($stan, arguments);
return $empty;
},
on = function(name, fn) {
$stan.on(name, function(evt, obj) {
// Shed the event object, who needs it?
fn(obj);
});
return $empty;
};
var Vent = {
trigger: trigger,
on: on
};
var events = {
All: "",
Custom1: "my1.event",
Custom2: "my2.event"
}
for (var evt in events) {
if (events.hasOwnProperty(evt) && evt !== 'All') {
events.All += events[evt] + " ";
}
}
Vent.on(events.Custom1, function () { alert(events.Custom1 + " trigger")});
Vent.on(events.All, function () { alert(events.All + " trigger")});
$("#btn").on('click', function () {
Vent.trigger(events.Custom1);
});
$("#btn2").on('click', function () {
Vent.trigger(events.Custom2);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id="btn">
Press Me
</button>
<button id="btn2">
Press Me 2
</button>
Upvotes: 0
Reputation: 25004
Try triggerAll
instead of trigger
:
(function($) {
$.fn.triggerAll = function(topics, data, delimiter) {
return this.each(function() {
var $this = $(this), chain = [], t = '';
delimiter = (delimiter || '.');
// rebuild chain
$.each(topics.split(delimiter), function(i,n) {
t += (i == 0 ? '' : delimiter) + n;
chain.push(t);
});
// append/prepend original topic?
data = (data || []);
data.push(topics);
$.each(chain, function(i,t) {
$this.trigger(t, data);
});
});
};
})(jQuery);
Granted, due to how jQuery handles triggering namespacing, triggering the "root" event actually fires the namespaced versions, so to get what you expect you'd need to use another character for the delimiter, like /
, and then declare your events like:
var $o = $('#whatever');
// this will be triggered for all events starting with 'root'
$o.on('root', function () { console.log(Array.prototype.slice.call(arguments, 0)); });
// some arbitrary way to fire custom events
$o.on('click', function () {
$o.triggerAll('root/custom1/subA', ['1st', '2nd'], '/');
$o.triggerAll('root/custom2', [3, 4, 5], '/');
});
Example in this fiddle
Upvotes: 1
Reputation: 3456
I fear the only way would be to list them all as a first argument of on method ...
$('#test').on('custom.ns1 custom.ns2 ...', function(evt){});
Which means annoying code review when the plugin is getting updated ...
Upvotes: 0