Adding and Removing Anonymous Event Handler

Adding and Removing Anonymous Event Handler

There's an MSDN page that talks about this:

How to Subscribe to and Unsubscribe from Events

Note in particular:

If you will not have to unsubscribe to [sic]
an event later, you can use the
addition assignment operator (+=) to
attach an anonymous method to the
event.

And also:

It is important to notice that you
cannot easily unsubscribe from an
event if you used an anonymous
function to subscribe to it. To
unsubscribe in this scenario, it is
necessary to go back to the code where
you subscribe to the event, store the
anonymous method in a delegate
variable, and then add the delegate to
the event . In general, we recommend
that you do not use anonymous
functions to subscribe to events if
you will have to unsubscribe from
the event at some later point in your
code.

Removing an anonymous event listener

There is no way to cleanly remove an event handler unless you stored a reference to the event handler at creation.

I will generally add these to the main object on that page, then you can iterate and cleanly dispose of them when done with that object.

Removing anonymous event handler

You can refer to your anonymous method from inside itself as long as you assign a delegate to a variable first:

EventHandler<SomeEventArgs> handler = null;
handler = (s, e) =>
{
_client.AddMemberToTeamCompleted -= handler;
callback(e.Result);
};

_client.AddMemberToTeamCompleted += handler;

Note that you need to declare the variable and assign it separately or the compiler will deem it uninitialized when you come to use it inside the method body.

Remove event listener with an anonymous function with a local scope variable

Yair Cohen's answer has the right idea, but it's missing something. addEventListener requires a function reference and not a function call. In his code, onStepIndex will get executed once and then never again.

To create a function reference and be able to feed it parameters and be able to remove the event listener later, you could use the concept called currying.

const onStepIndex = function(stepIndex) {
return function actualOnStepIndex(event) {
console.log(event);
console.log(stepIndex);
}
}
const handlers = [];

const startSelectNode = (stepIndex) => {
document.addEventListener("click", handlers[stepIndex] = onStepIndex(stepIndex), true);
};

const stopSelectNode = (stepIndex) => {
document.removeEventListener("click", handlers[stepIndex], true);
};

startSelectNode(1); // This adds the event listener for stepIndex = 1
stopSelectNode(1); // This removes the event listener for stepIndex = 1

Basically, by calling onStepIndex you return the actual function, which is now the event handler. We saved the reference to the function in the handlers array and we need that reference if we later want to call removeEventListener.

How can I remove an event listener that's an anonymous function?

You can't do it with an anonymous function. You have to have a reference to the listener function.

Regarding your issues with having this undefined -- this is a common problem in JS and it's worth googling a bit. You can either use bind and store the result in a variable, or use arrow functions if you have them.

Removing anonymous event handlers with some parameters

it will not work cause drawEvent is local variable and next time I call CoupleOverlay, it will create new one.

Indeed. You'd basically need to keep an instance variable instead of a local variable. The instance variable would effectively be "the currently subscribed event handler". Then in CoupleOverlay you'd remove that event handler, create a new one (storing it in the variable) and resubscribing with it.

An alternative would be to use a single event handler, but keep the "current" overlay and map visual as instance variables, used by the event handler. The CoupleOverlay method would then just need to update those variables.

How do I Unregister 'anonymous' event handler

If you need to unregister an event, I recommend avoiding anonymous delegates for the event handler.

This is one case where assigning this to a local method is better - you can unsubscribe from the event cleanly.

Remove anonymous event listeners before adding any new ones

using felix's suggestion

var setSingletonEventListener = (function(element){
var handlers = {};
return function(evtName, func){
handlers.hasOwnProperty(evtName) && element.removeEventListener(evtName, handlers[evtName]);
if (func) {
handlers[evtName] = func;
element.addEventListener(evtName, func);
} else {
delete handlers[evtName];
}
};
})(document);

setSingletonEventListener("custom event", function(){

});

//replaces the previous
setSingletonEventListener("custom event", function(){

});

//removes the listener, if any
setSingletonEventListener("custom event");


Related Topics



Leave a reply



Submit