Skip to content

Instantly share code, notes, and snippets.

@BeerOnBeard
Created January 14, 2017 19:54
Show Gist options
  • Save BeerOnBeard/97a50f23d31dce4203eec9a719c2769d to your computer and use it in GitHub Desktop.
Save BeerOnBeard/97a50f23d31dce4203eec9a719c2769d to your computer and use it in GitHub Desktop.
Ability to dispose subscribers from a view model that contains an observable that will be subscribed to.
/*
I have a collection of view models and I want to track a property on each of them to notify the parent.
However, if the child is removed from the array, the view model will live in memory with no hope of garbage
collection because there is still a subscriber that has a reference to it.
To solve this, I've added a .dispose() method on the view model that will iterate over the change subscriptions
on properties that I know will be subscribed to by higher view models and dispose of the subscriptions from here.
That way I don't have to track the subscriptions in the higher view model. All I have to do is call the .dispose()
method on an item if I remove it from the array.
*/
var ViewModel = function() {
var self = this;
self.watchMe = ko.observable();
self.dispose = function() {
ko.utils.arrayForEach(self.watchMe._subscriptions.change, function(sub) {
sub.dispose();
});
};
}
var vm1 = new ViewModel();
var vm2 = new ViewModel();
var obsArray = ko.observableArray([ vm2, vm1 ]); // reverse so I can .pop() vm1
var callback = function(msg) {
console.log('callback', msg);
}
ko.utils.arrayForEach(obsArray(), function(item) {
item.watchMe.subscribe(callback);
});
vm1.watchMe('change');
var deletedVm = obsArray.pop();
deletedVm.dispose();
// they're all gone!!!!
console.log('subscribers on popped vm', vm1.x._subscriptions);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment