How to dispose of a viewmodel in Durandal after deactivation

755 views Asked by At

I am using durandal and requirejs to compose my viewmodels. I am also hooking into the composition life-cycle callback method deactivate every time I navigate away from the view. I want to dispose of my viewmodel in this method.

I've tried delete this, this = undefined but they don't seem to work.

I am also using the durandal event aggregator like this:

self.activate = () => {
        App.trigger("testEvent");
    };

    App.on("testEvent").then(() =>
    {
        alert('Event Triggered!');
    });

So every time the viewmodel is loaded, the event will be triggered. Now, if I the navigate away from the view, then navigate back (hence the viewmodel will be loaded again), then the event will be triggered twice. If I navigate to the view for the 3rd time, the event will be triggered 3 times and so on and so forth. So the previous viewmodels are still present, which is why the the durandal event is being triggered by each viewmodel. Therefore, to fix this issue, I need to dispose of the viewmodels in deactivate, how can I do this?

Note. the viewmodels in question are transient, not singleton.

2

There are 2 answers

2
Jason Spake On BEST ANSWER

Durandal also provides an "attached" lifecycle hook which only gets triggers when the view is attached in the DOM. If you place your event subscriptions here they should only get subscribed to the one time.

http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks

EDIT:

As far as unsubscribing from events goes, if you save the return value from the subscription you can call .off later in your deactivate or detached methods

var subscription = App.on("testEvent");
...
subscription.off();

http://durandaljs.com/documentation/Leveraging-Publish-Subscribe.html

The viewmodel itself is just a managed javascript object and will be disposed automatically after all references to it disappear.

0
MattjeS On

It's probably keeping a reference to your view model because you are subscribing to the event 'testEvent' but never unsubscribe. I'm not an expert in how it would dispose in javascript but have come across similar scenarios in .net

Your event won't get triggered three times, it would get triggered once but the event handler function will get called per subscription so after 3 navigations, 3 times.

Try unsubscribing in the deactivate method and see if it works. This will at least stop the event handler firing three times. I'm not certain this will dispose of your view model correctly though.