-
Notifications
You must be signed in to change notification settings - Fork 2.5k
fix(5007): Reduced the amount of digest cycles initiated by the grid. #6072
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Re-implemented some of @csvan's work with PR angular-ui#5829 and improved refreshCanvas function. 5007
return row.id; | ||
var gridApi; | ||
|
||
$scope.gridOptions = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to combine the multiple calls to $scope.gridOptions.[something] into one object definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea
|
||
$scope.gridOptions.columnDefs = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This moved to line 31
}; | ||
$scope.gridOptions.getRowIdentity = function(row) { | ||
|
||
function getRowId(row) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function was repeated for getRowIndentity and rowIdentity, so I combined them.
}]); | ||
</file> | ||
<file name="index.html"> | ||
<div ng-controller="MainCtrl"> | ||
<button id="filterToggle" type="button" class="btn btn-success" ng-click="toggleFilterRow()">Toggle Filter</button> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find myself needing to test this a lot and I frequently see question about how to implement something like this, so I added it to this demo.
$attrs.$observe('uiGridColumns', function(value) { | ||
self.grid.options.columnDefs = value; | ||
deregFunctions.push( $attrs.$observe('uiGridColumns', function(value) { | ||
self.grid.options.columnDefs = angular.isString(value) ? angular.fromJson(value) : value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While writing unit tests, I realized there was a mistake with this watch. Since this is an attribute watch, the value of it might be a string that needs to be converted to an object.
} | ||
|
||
// prevents an error from being thrown when the array is not defined yet and fastWatch is on | ||
function getSize(array) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, while writing unit tests, I realized we don't handle the case for where data is undefined and fastWatch is on. This will prevent issues with that.
else { | ||
$timeout(init); | ||
} else { | ||
$scope.$applyAsync(init); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should prevent an unnecessary digest cycle by pig backing on the next available cycle.
// Bind to window resize events | ||
angular.element($window).on('resize', gridResize); | ||
|
||
// Unbind from window resize events when the grid is destroyed | ||
$elm.on('$destroy', function () { | ||
angular.element($window).off('resize', gridResize); | ||
deregisterLeftWatcher(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cleaning up possible memory leaks
@@ -595,10 +595,10 @@ angular.module('ui.grid') | |||
callback.types.indexOf( type ) !== -1 || | |||
type === uiGridConstants.dataChange.ALL ) { | |||
if (callback._this) { | |||
callback.callback.apply(callback._this,this); | |||
callback.callback.apply(callback._this, this, options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Giving us a way to pass options into a registered callback. This allowed me to prevent buildColumns from being triggered multiple time during initialization. See line 74 of ui-grid.js
|
||
self.grid.callDataChangeCallbacks(uiGridConstants.dataChange.COLUMN); | ||
}).catch(angular.noop); | ||
self.grid.callDataChangeCallbacks(uiGridConstants.dataChange.COLUMN, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent buildColumns from being triggered multiple time during initialization. See lines 598 and 601 of Grid.js.
@@ -84,12 +84,10 @@ | |||
// gridUtil.logDebug('dataWatch fired'); | |||
var promises = []; | |||
|
|||
if ( self.grid.options.fastWatch ){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the fastWatch condition for expecting data to be a string because based on line 62 of this file, strings for data are supported without fastWatch.
|
||
self.grid.preCompileCellTemplates(); | ||
|
||
self.grid.callDataChangeCallbacks(uiGridConstants.dataChange.COLUMN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line was causing buildColumns to be triggered a second time.
Grid.prototype.columnRefreshCallback = function columnRefreshCallback( grid ){ | ||
grid.buildColumns(); | ||
Grid.prototype.columnRefreshCallback = function columnRefreshCallback(grid, options){ | ||
grid.buildColumns(options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows the columnRefreshCallback to pre-compile the cell templates when needed.
@@ -664,7 +664,7 @@ | |||
allowCellFocus: true | |||
}; | |||
|
|||
uiGridCtrl.grid.addRowHeaderColumn(selectionRowHeaderDef, 0); | |||
uiGridCtrl.grid.addRowHeaderColumn(selectionRowHeaderDef, 0, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a new attribute to prevent build columns from being triggered multiple times in a row. ColumnDefs is now responsible for building the columns. See line 763 of Grid.js
@@ -715,7 +715,7 @@ | |||
}; | |||
|
|||
rowHeaderColumnDef.visible = grid.options.treeRowHeaderAlwaysVisible; | |||
grid.addRowHeaderColumn( rowHeaderColumnDef, -100 ); | |||
grid.addRowHeaderColumn(rowHeaderColumnDef, -100, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a new attribute to prevent build columns from being triggered multiple times in a row. ColumnDefs is now responsible for building the columns. See line 763 of Grid.js
I was just noticing the massive amount of digest cycles that ui-grid forces, especially in my case when I'm swapping large datasets in and out while using ui-grid-auto-resize to make all rows visible. |
@mportuga great work! |
return row.id; | ||
var gridApi; | ||
|
||
$scope.gridOptions = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good idea
$scope.toggleFilterRow = function() { | ||
$scope.gridOptions.enableFiltering = !$scope.gridOptions.enableFiltering; | ||
gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is this used? Is it a new button designed into the grid? Why do you need to notifyDataChange?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is a new button. And the grid will not update unless the event is fired.
Re-implemented some of @csvan's work with PR #5829 and improved refreshCanvas function.
Also, update the All features tutorial to add a toggle button for the filter row and improved coverage in ui-grid.js
5007