Skip to content

Commit 75f98c3

Browse files
Portugal, MarceloPortugal, Marcelo
Portugal, Marcelo
authored and
Portugal, Marcelo
committed
fix(5007): Reduced the amount of digest cycles initiated by the grid.
Re-implemented some of @csvan's work with PR #5829 and improved refreshCanvas function. 5007
1 parent c6b0592 commit 75f98c3

File tree

11 files changed

+572
-350
lines changed

11 files changed

+572
-350
lines changed

misc/tutorial/401_AllFeatures.ngdoc

+44-37
Original file line numberDiff line numberDiff line change
@@ -15,44 +15,52 @@ All features are enabled to get an idea of performance
1515

1616
app.controller('MainCtrl', ['$scope', '$http', '$timeout', '$interval', 'uiGridConstants', 'uiGridGroupingConstants',
1717
function ($scope, $http, $timeout, $interval, uiGridConstants, uiGridGroupingConstants) {
18-
19-
$scope.gridOptions = {};
20-
$scope.gridOptions.data = 'myData';
21-
$scope.gridOptions.enableCellEditOnFocus = true;
22-
$scope.gridOptions.enableColumnResizing = true;
23-
$scope.gridOptions.enableFiltering = true;
24-
$scope.gridOptions.enableGridMenu = true;
25-
$scope.gridOptions.showGridFooter = true;
26-
$scope.gridOptions.showColumnFooter = true;
27-
$scope.gridOptions.fastWatch = true;
28-
29-
$scope.gridOptions.rowIdentity = function(row) {
30-
return row.id;
18+
var gridApi;
19+
20+
$scope.gridOptions = {
21+
data: 'myData',
22+
enableCellEditOnFocus: true,
23+
enableColumnResizing: true,
24+
enableFiltering: true,
25+
enableGridMenu: true,
26+
showGridFooter: true,
27+
showColumnFooter: true,
28+
fastWatch: true,
29+
rowIdentity: getRowId,
30+
getRowIdentity: getRowId,
31+
columnDefs: [
32+
{ name:'id', width:50 },
33+
{ name:'name', width:100 },
34+
{ name:'age', width:100, enableCellEdit: true, aggregationType:uiGridConstants.aggregationTypes.avg, treeAggregationType: uiGridGroupingConstants.aggregation.AVG },
35+
{ name:'address.street', width:150, enableCellEdit: true },
36+
{ name:'address.city', width:150, enableCellEdit: true },
37+
{ name:'address.state', width:50, enableCellEdit: true },
38+
{ name:'address.zip', width:50, enableCellEdit: true },
39+
{ name:'company', width:100, enableCellEdit: true },
40+
{ name:'email', width:100, enableCellEdit: true },
41+
{ name:'phone', width:200, enableCellEdit: true },
42+
{ name:'about', width:300, enableCellEdit: true },
43+
{ name:'friends[0].name', displayName:'1st friend', width:150, enableCellEdit: true },
44+
{ name:'friends[1].name', displayName:'2nd friend', width:150, enableCellEdit: true },
45+
{ name:'friends[2].name', displayName:'3rd friend', width:150, enableCellEdit: true },
46+
{ name:'agetemplate',field:'age', width:150, cellTemplate: '<div class="ui-grid-cell-contents"><span>Age 2:{{COL_FIELD}}</span></div>' },
47+
{ name:'Is Active',field:'isActive', width:150, type:'boolean' },
48+
{ name:'Join Date',field:'registered', cellFilter:'date', width:150, type:'date', enableFiltering:false },
49+
{ name:'Month Joined',field:'registered', cellFilter: 'date:"MMMM"', filterCellFiltered:true, sortCellFiltered:true, width:150, type:'date' }
50+
],
51+
onRegisterApi: function onRegisterApi(registeredApi) {
52+
gridApi = registeredApi;
53+
}
3154
};
32-
$scope.gridOptions.getRowIdentity = function(row) {
55+
56+
function getRowId(row) {
3357
return row.id;
34-
};
58+
}
3559

36-
$scope.gridOptions.columnDefs = [
37-
{ name:'id', width:50 },
38-
{ name:'name', width:100 },
39-
{ name:'age', width:100, enableCellEdit: true, aggregationType:uiGridConstants.aggregationTypes.avg, treeAggregationType: uiGridGroupingConstants.aggregation.AVG },
40-
{ name:'address.street', width:150, enableCellEdit: true },
41-
{ name:'address.city', width:150, enableCellEdit: true },
42-
{ name:'address.state', width:50, enableCellEdit: true },
43-
{ name:'address.zip', width:50, enableCellEdit: true },
44-
{ name:'company', width:100, enableCellEdit: true },
45-
{ name:'email', width:100, enableCellEdit: true },
46-
{ name:'phone', width:200, enableCellEdit: true },
47-
{ name:'about', width:300, enableCellEdit: true },
48-
{ name:'friends[0].name', displayName:'1st friend', width:150, enableCellEdit: true },
49-
{ name:'friends[1].name', displayName:'2nd friend', width:150, enableCellEdit: true },
50-
{ name:'friends[2].name', displayName:'3rd friend', width:150, enableCellEdit: true },
51-
{ name:'agetemplate',field:'age', width:150, cellTemplate: '<div class="ui-grid-cell-contents"><span>Age 2:{{COL_FIELD}}</span></div>' },
52-
{ name:'Is Active',field:'isActive', width:150, type:'boolean' },
53-
{ name:'Join Date',field:'registered', cellFilter:'date', width:150, type:'date', enableFiltering:false },
54-
{ name:'Month Joined',field:'registered', cellFilter: 'date:"MMMM"', filterCellFiltered:true, sortCellFiltered:true, width:150, type:'date' }
55-
];
60+
$scope.toggleFilterRow = function() {
61+
$scope.gridOptions.enableFiltering = !$scope.gridOptions.enableFiltering;
62+
gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);
63+
};
5664

5765
$scope.callsPending = 0;
5866

@@ -90,13 +98,12 @@ All features are enabled to get an idea of performance
9098
$timeout.cancel(timeout);
9199
$interval.cancel(sec);
92100
});
93-
94101
};
95-
96102
}]);
97103
</file>
98104
<file name="index.html">
99105
<div ng-controller="MainCtrl">
106+
<button id="filterToggle" type="button" class="btn btn-success" ng-click="toggleFilterRow()">Toggle Filter</button>
100107
<button id="refreshButton" type="button" class="btn btn-success" ng-click="refreshData()">Refresh Data</button> <strong>Calls Pending:</strong> <span ng-bind="callsPending"></span>
101108
<br>
102109
<br>

src/features/selection/js/selection.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@
664664
allowCellFocus: true
665665
};
666666

667-
uiGridCtrl.grid.addRowHeaderColumn(selectionRowHeaderDef, 0);
667+
uiGridCtrl.grid.addRowHeaderColumn(selectionRowHeaderDef, 0, true);
668668
}
669669

670670
var processorSet = false;

src/features/selection/test/uiGridSelectionDirective.spec.js

+64-36
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,56 @@ describe('ui.grid.selection uiGridSelectionDirective', function() {
55
gridCtrl,
66
$compile,
77
$rootScope,
8+
$timeout,
89
uiGridConstants;
910

10-
beforeEach(module('ui.grid.selection'));
11+
/*
12+
NOTES
13+
- We have to flush $timeout because the header calculations are done post-$timeout, as that's when the header has been fully rendered.
14+
- We have to actually attach the grid element to the document body, otherwise it will not have a rendered height.
15+
*/
16+
function compileUiGridSelectionDirective(parentScope) {
17+
var elm = angular.element('<div style="width: 300px; height: 500px" ui-grid="options" ui-grid-selection></div>');
18+
19+
document.body.appendChild(elm[0]);
20+
$compile(elm)(parentScope);
21+
$timeout.flush();
22+
parentScope.$digest();
1123

12-
beforeEach(inject(function(_$rootScope_, _$compile_, _uiGridConstants_) {
13-
$compile = _$compile_;
14-
$rootScope = _$rootScope_;
15-
uiGridConstants = _uiGridConstants_;
24+
return elm;
25+
}
1626

17-
parentScope = $rootScope.$new();
27+
beforeEach(function() {
28+
module('ui.grid.selection');
1829

19-
parentScope.options = {
20-
columnDefs : [{field: 'id'}]
21-
};
30+
inject(function(_$compile_, _$rootScope_, _$timeout_, _uiGridConstants_) {
31+
$compile = _$compile_;
32+
$rootScope = _$rootScope_;
33+
$timeout = _$timeout_;
34+
uiGridConstants = _uiGridConstants_;
35+
});
2236

23-
parentScope.options.isRowSelectable = function(gridRow) {
24-
return gridRow.entity.id % 2 === 0;
37+
parentScope = $rootScope.$new();
38+
parentScope.options = {
39+
columnDefs : [{field: 'id'}],
40+
data: [],
41+
isRowSelectable: function(gridRow) {
42+
return gridRow.entity.id % 2 === 0;
43+
}
2544
};
2645

27-
parentScope.options.data = [];
2846
for (var i = 0; i < 10; i++) {
2947
parentScope.options.data.push({id: i});
3048
}
3149

32-
var tpl = '<div ui-grid="options" ui-grid-selection options="options"></div>';
33-
elm = $compile(tpl)(parentScope);
34-
35-
parentScope.$digest();
50+
elm = compileUiGridSelectionDirective(parentScope);
3651
scope = elm.scope();
37-
3852
gridCtrl = elm.controller('uiGrid');
53+
});
3954

40-
}));
55+
it('should add the row header selection buttons', function() {
56+
expect($(elm).find('.ui-grid-header .ui-grid-selection-row-header-buttons').length).toEqual(1);
57+
});
4158

4259
it('should set the "enableSelection" field of the row using the function specified in "isRowSelectable"', function() {
4360
for (var i = 0; i < gridCtrl.grid.rows.length; i++) {
@@ -56,25 +73,10 @@ describe('ui.grid.selection uiGridSelectionDirective', function() {
5673
});
5774

5875
describe('with filtering turned on', function () {
59-
var elm, $timeout;
60-
61-
/*
62-
NOTES
63-
- We have to flush $timeout because the header calculations are done post-$timeout, as that's when the header has been fully rendered.
64-
- We have to actually attach the grid element to the document body, otherwise it will not have a rendered height.
65-
*/
66-
67-
beforeEach(inject(function (_$timeout_) {
68-
$timeout = _$timeout_;
69-
76+
beforeEach(function () {
7077
parentScope.options.enableFiltering = true;
71-
72-
elm = angular.element('<div style="width: 300px; height: 500px" ui-grid="options" ui-grid-selection></div>');
73-
document.body.appendChild(elm[0]);
74-
$compile(elm)(parentScope);
75-
$timeout.flush();
76-
parentScope.$digest();
77-
}));
78+
elm = compileUiGridSelectionDirective(parentScope);
79+
});
7880

7981
afterEach(function () {
8082
$(elm).remove();
@@ -95,4 +97,30 @@ describe('ui.grid.selection uiGridSelectionDirective', function() {
9597
expect(noFilteringHeight < filteringHeight).toBe(true);
9698
});
9799
});
100+
101+
describe('when row header selection is turned off', function() {
102+
beforeEach(function () {
103+
parentScope.options.enableRowHeaderSelection = false;
104+
elm = compileUiGridSelectionDirective(parentScope);
105+
});
106+
107+
it('should not add the row header selection buttons', function() {
108+
expect($(elm).find('.ui-grid-header .ui-grid-selection-row-header-buttons').length).toEqual(0);
109+
});
110+
});
111+
112+
describe('when isRowSelectable is not defined', function() {
113+
beforeEach(function () {
114+
delete parentScope.options.isRowSelectable;
115+
elm = compileUiGridSelectionDirective(parentScope);
116+
gridCtrl = elm.controller('uiGrid');
117+
});
118+
119+
it('should not define enableSelection', function() {
120+
for (var i = 0; i < gridCtrl.grid.rows.length; i++) {
121+
var currentRow = gridCtrl.grid.rows[i];
122+
expect(currentRow.enableSelection).toBeUndefined();
123+
}
124+
});
125+
});
98126
});

src/features/tree-base/js/tree-base.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@
715715
};
716716

717717
rowHeaderColumnDef.visible = grid.options.treeRowHeaderAlwaysVisible;
718-
grid.addRowHeaderColumn( rowHeaderColumnDef, -100 );
718+
grid.addRowHeaderColumn(rowHeaderColumnDef, -100, true);
719719
},
720720

721721

src/features/tree-base/test/tree-base.spec.js

+28-35
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
describe('ui.grid.treeBase uiGridTreeBaseService', function () {
2-
var uiGridTreeBaseService;
3-
var uiGridTreeBaseConstants;
4-
var gridClassFactory;
5-
var grid;
6-
var $rootScope;
7-
var $scope;
8-
var GridRow;
9-
var gridUtil;
10-
var uiGridConstants;
11-
12-
beforeEach(module('ui.grid.treeBase'));
13-
14-
beforeEach(inject(function (_uiGridTreeBaseService_,_gridClassFactory_, $templateCache, _uiGridTreeBaseConstants_,
15-
_$rootScope_, _GridRow_, _gridUtil_, _uiGridConstants_) {
16-
uiGridTreeBaseService = _uiGridTreeBaseService_;
17-
uiGridTreeBaseConstants = _uiGridTreeBaseConstants_;
18-
gridClassFactory = _gridClassFactory_;
19-
$rootScope = _$rootScope_;
2+
var uiGridTreeBaseService,
3+
uiGridTreeBaseConstants,
4+
gridClassFactory,
5+
grid,
6+
$rootScope,
7+
$scope,
8+
GridRow,
9+
gridUtil,
10+
uiGridConstants;
11+
12+
beforeEach(function() {
13+
module('ui.grid.treeBase');
14+
15+
inject(function (_uiGridTreeBaseService_,_gridClassFactory_, $templateCache, _uiGridTreeBaseConstants_,
16+
_$rootScope_, _GridRow_, _gridUtil_, _uiGridConstants_) {
17+
uiGridTreeBaseService = _uiGridTreeBaseService_;
18+
uiGridTreeBaseConstants = _uiGridTreeBaseConstants_;
19+
gridClassFactory = _gridClassFactory_;
20+
$rootScope = _$rootScope_;
21+
GridRow = _GridRow_;
22+
gridUtil = _gridUtil_;
23+
uiGridConstants = _uiGridConstants_;
24+
});
2025
$scope = $rootScope.$new();
21-
GridRow = _GridRow_;
22-
gridUtil = _gridUtil_;
23-
uiGridConstants = _uiGridConstants_;
2426

2527
grid = gridClassFactory.createGrid({});
2628
grid.options.columnDefs = [
@@ -30,6 +32,7 @@ describe('ui.grid.treeBase uiGridTreeBaseService', function () {
3032
{field: 'col3'}
3133
];
3234

35+
spyOn(grid, 'addRowHeaderColumn').and.callThrough();
3336
uiGridTreeBaseService.initializeGrid(grid, $scope);
3437
$scope.$apply();
3538

@@ -44,24 +47,11 @@ describe('ui.grid.treeBase uiGridTreeBaseService', function () {
4447
data[7].$$treeLevel = 0;
4548
data[9].$$treeLevel = 1;
4649

47-
// data = [
48-
// { col0: 'a_0', col1: 0, col2: 'c_0', col3: 0, '$$treeLevel': 0 } ,
49-
// { col0: 'a_0', col1: 0, col2: 'c_1', col3: 1, '$$treeLevel': 1 },
50-
// { col0: 'a_0', col1: 1, col2: 'c_2', col3: 2 },
51-
// { col0: 'a_0', col1: 1, col2: 'c_3', col3: 3, '$$treeLevel': 1 },
52-
// { col0: 'a_1', col1: 2, col2: 'c_4', col3: 4, '$$treeLevel': 2 },
53-
// { col0: 'a_1', col1: 2, col2: 'c_5', col3: 5 },
54-
// { col0: 'a_1', col1: 3, col2: 'c_6', col3: 6 },
55-
// { col0: 'a_1', col1: 3, col2: 'c_7', col3: 7, '$$treeLevel': 0 },
56-
// { col0: 'a_2', col1: 4, col2: 'c_8', col3: 8 },
57-
// { col0: 'a_2', col1: 4, col2: 'c_9', col3: 9, '$$treeLevel': 1 }
58-
// ];
59-
6050
grid.options.data = data;
6151

6252
grid.buildColumns();
6353
grid.modifyRows(grid.options.data);
64-
}));
54+
});
6555

6656

6757
describe( 'initializeGrid and defaultGridOptions', function() {
@@ -90,6 +80,9 @@ describe('ui.grid.treeBase uiGridTreeBaseService', function () {
9080
enableExpandAll: true
9181
});
9282
});
83+
it('should call addRowHeaderColumn', function() {
84+
expect(grid.addRowHeaderColumn).toHaveBeenCalledWith(jasmine.any(Object), -100, true);
85+
});
9386
});
9487

9588

0 commit comments

Comments
 (0)