Skip to content

Commit

Permalink
fix(uiGridRow): Fix memory leak
Browse files Browse the repository at this point in the history
Bindings were being attached to the uiGridRow scope but never removed
because the scope was not being destroyed even though child elements were
being added. This was fixed by creating new scopes for uiGridRow when
compiled/re-compiled.

Also, added an element-based `$destroy` handler for ui-grid-cell. It
already had one for the $scope.
  • Loading branch information
c0bra committed Dec 22, 2014
1 parent a547a52 commit 64d3918
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/js/core/directives/ui-grid-cell.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ angular.module('ui.grid').directive('uiGridCell', ['$compile', '$parse', 'gridUt
rowWatchDereg();
};


$scope.$on( '$destroy', deregisterFunction );
$elm.on( '$destroy', deregisterFunction );
}
};
}
Expand Down
27 changes: 20 additions & 7 deletions src/js/core/directives/ui-grid-row.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,26 @@
$scope.colContainer = containerCtrl.colContainer;

// Function for attaching the template to this scope
var clonedElement, cloneScope;
function compileTemplate() {
var compiledElementFn = $scope.row.compiledElementFn;

compiledElementFn($scope, function (clonedElement, scope) {
$elm.empty().append(clonedElement);
// Create a new scope for the contents of this row, so we can destroy it later if need be
var newScope = $scope.$new();

compiledElementFn(newScope, function (newElm, scope) {
// If we already have a cloned element, we need to remove it and destroy its scope
if (clonedElement) {
clonedElement.remove();
cloneScope.$destroy();
}

// Empty the row and append the new element
$elm.empty().append(newElm);

// Save the new cloned element and scope
clonedElement = newElm;
cloneScope = newScope;
});
}

Expand All @@ -38,18 +53,16 @@
// If the row's compiled element function changes, we need to replace this element's contents with the new compiled template
$scope.$watch('row.compiledElementFn', function (newFunc, oldFunc) {
if (newFunc !== oldFunc) {
newFunc($scope, function (clonedElement, scope) {
$elm.empty().append(clonedElement);
});
compileTemplate();
}
});
},
post: function($scope, $elm, $attrs, controllers) {
var uiGridCtrl = controllers[0];
var containerCtrl = controllers[1];

//add optional reference to externalScopes function to scope
//so it can be retrieved in lower elements
// Sdd optional reference to externalScopes function to scope
// so it can be retrieved in lower elements
$scope.getExternalScopes = uiGridCtrl.getExternalScopes;
}
};
Expand Down

0 comments on commit 64d3918

Please sign in to comment.