Reputation: 1806
Alright so I have a viewport divided into two halves, top and bottom. The top half has combo boxes and input fields that are always visible, the bottom half has a tab panel with multiple tabs.
When I change one of the static combo boxes on the top half, I'll call it combo box A
, it fires an event and in its event handler, A_handler
, it will attempt to style another combo box in one of the tabs, I'll call it combo box B
, but it may do one of two things.
Combo box B
is visible on tab 2
, not 1
.
So then:
1) If tab 1
is active, it will setup an event handler to style combo box B
for when tab 2
is made active.
2) Otherwise, it will just immediately style it.
So here's the problem: The initial combo box, A
, can style combo box B
one of two possible ways, depending on the selection, say red
and blue
.
So imagine the situation where tab 1
is visible, and I select the option to style B
as red
, then the event handler is created for when tab 2
is activated. But then, without activating tab 2
, I change the option again in combo A
, to make box B
as blue
.
At this point, I need it to remove the first event handler so that only one is fired.
I do not have a reference to the event handlers, but I have named them.
I have created functions to acquire the list of event listeners on tab 2
, and know the name of the listener to remove, so I can match names, but the scopes are not the same when I attempt to remove them with the tab's removeListener
, so nothing happens.
Upvotes: 0
Views: 3009
Reputation: 3251
You may set event handlers to work only once:
someItem.on('event', function() {
// ... bla bla bla ...
}, scope, {single:true});
Upvotes: 1
Reputation: 1806
Solved
Eventually found the solution to this.
The un
or removeListener
functions are setup like this:
un( eventName, fn, [scope] )
My problem was that I did not have a reference to the specific handler to pass in for fn
The solution involves finding the fn
ref by searching with the fn name.
So when the event listener is created, it is setup with a name:
myTab.on('activate', function doSomeStuff() {
Later on when I need to check if it exists/possibly remove it:
objectHasNamedListener: function(obj, eventType, name) {
var listeners = obj.events[eventType].listeners;
//trim functionality since .trim() doesn't exist in old IE
name = name.replace(/^\s+|\s+$/g, '');
if (listeners != undefined) {
for (var i = 0; i < listeners.length; i++) {
var func = listeners[i].fn;
var funcStr = func.toString();
var funcName = funcStr.substr('function'.length);
funcName = funcName.substr(0, funcName.indexOf('('));
funcName = funcName.replace(/^\s+|\s+$/g, '');
if (funcName == name) {
return true;
}
}
}
return false;
},
And if that returns true, get the reference to that handler:
if (this.objectHasNamedListener(myTab, "activate", "doSomeStuff")) {
var listener = this.getNamedListener(myTab, "activate", "doSomeStuff");
myTab.removeListener("activate", listener, this);
}
getNamedListener: function(obj, eventType, name) {
var listeners = obj.events[eventType].listeners;
name = name.replace(/^\s+|\s+$/g, '');
if (listeners != undefined) {
for (var i = 0; i < listeners.length; i++) {
var func = listeners[i].fn;
var funcStr = func.toString();
var funcName = funcStr.substr('function'.length);
funcName = funcName.substr(0, funcName.indexOf('('));
funcName = funcName.replace(/^\s+|\s+$/g, '');
if (funcName == name) {
return func;
}
}
}
return null;
},
The other caveat is that the listener had to be created and removed with the same scope passed in, despite the fact that it is listed as [optional] in the API, so passing in this worked fine
Upvotes: 0