Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.

Commit d3f42dd

Browse files
Ghislain BeaulacGhislain Beaulac
authored andcommitted
fix(backend): clear filters was calling too many queries (1x/filter)
- this commit is mostly all perf improvement, calling only the necessary amount of queries to backend - when having multiple filters it should call only 1 query to clear all filters - add new "clearAllFiltersAndSorts()" method to clear both in 1 query - add extra argument to clearSorting to skip querying (clear both filters+sorts should call only 1 query)
1 parent ceb8337 commit d3f42dd

File tree

6 files changed

+70
-18
lines changed

6 files changed

+70
-18
lines changed

src/app/modules/angular-slickgrid/models/backendService.interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ export interface BackendService {
2020
/** Build and the return the backend service query string */
2121
buildQuery: (serviceOptions?: BackendServiceOption) => string;
2222

23+
/** Clear all sorts */
24+
clearFilters?: () => void;
25+
26+
/** Clear all sorts */
27+
clearSorters?: () => void;
28+
2329
/** initialize the backend service with certain options */
2430
init?: (serviceOptions?: BackendServiceOption, pagination?: Pagination, grid?: any) => void;
2531

src/app/modules/angular-slickgrid/services/filter.service.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,15 @@ export class FilterService {
111111
debounceTypingDelay = backendApi.filterTypingDebounce || DEFAULT_FILTER_TYPING_DEBOUNCE;
112112
}
113113

114-
// call the service to get a query back
115-
if (debounceTypingDelay > 0) {
116-
clearTimeout(timer);
117-
timer = setTimeout(() => this.executeBackendCallback(event, args, startTime, backendApi), debounceTypingDelay);
118-
} else {
119-
this.executeBackendCallback(event, args, startTime, backendApi);
114+
// query backend, except when it's called by a ClearFilters then we won't
115+
if (args && !args.clearFilterTriggered) {
116+
// call the service to get a query back
117+
if (debounceTypingDelay > 0) {
118+
clearTimeout(timer);
119+
timer = setTimeout(() => this.executeBackendCallback(event, args, startTime, backendApi), debounceTypingDelay);
120+
} else {
121+
this.executeBackendCallback(event, args, startTime, backendApi);
122+
}
120123
}
121124
} catch (error) {
122125
onBackendError(error, backendApi);
@@ -126,7 +129,7 @@ export class FilterService {
126129
async executeBackendCallback(event: KeyboardEvent, args: any, startTime: Date, backendApi: BackendServiceApi) {
127130
const query = await backendApi.service.processOnFilterChanged(event, args);
128131

129-
// emit an onFilterChanged event when it's not called by clearAllFilters
132+
// emit an onFilterChanged event when it's not called by a clear filter
130133
if (args && !args.clearFilterTriggered) {
131134
this.emitFilterChanged('remote');
132135
}
@@ -161,7 +164,7 @@ export class FilterService {
161164
if (columnId != null) {
162165
dataView.refresh();
163166
}
164-
// emit an onFilterChanged event when it's not called by clearAllFilters
167+
// emit an onFilterChanged event when it's not called by a clear filter
165168
if (args && !args.clearFilterTriggered) {
166169
this.emitFilterChanged('local');
167170
}
@@ -210,10 +213,14 @@ export class FilterService {
210213
}
211214

212215
// we also need to refresh the dataView and optionally the grid (it's optional since we use DataView)
213-
if (this._dataView) {
216+
if (this._dataView && this._grid) {
214217
this._dataView.refresh();
215218
this._grid.invalidate();
216-
this._grid.render();
219+
}
220+
221+
// when using backend service, we need to query only once so it's better to do it here
222+
if (this._gridOptions && this._gridOptions.backendServiceApi) {
223+
this.executeBackendCallback(undefined, { clearFilterTriggered: true, grid: this._grid, columnFilters: this._columnFilters }, new Date(), this._gridOptions.backendServiceApi);
217224
}
218225

219226
// emit an event when filters are all cleared

src/app/modules/angular-slickgrid/services/graphql.service.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ export class GraphqlService implements BackendService {
169169
.replace(/\}$/, '');
170170
}
171171

172+
clearFilters() {
173+
this._currentFilters = [];
174+
this.updateOptions({ filteringOptions: [] });
175+
}
176+
177+
clearSorters() {
178+
this._currentSorters = [];
179+
this.updateOptions({ sortingOptions: [] });
180+
}
181+
172182
init(serviceOptions?: GraphqlServiceOption, pagination?: Pagination, grid?: any): void {
173183
this._grid = grid;
174184
this.options = serviceOptions || {};

src/app/modules/angular-slickgrid/services/grid-odata.service.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ export class GridOdataService implements BackendService {
5555
return this.odataService.buildQuery();
5656
}
5757

58+
clearFilters() {
59+
this._currentFilters = [];
60+
this.updateOptions({ filteringOptions: [] });
61+
}
62+
63+
clearSorters() {
64+
this._currentSorters = [];
65+
this.updateOptions({ sortingOptions: [] });
66+
}
67+
5868
init(options: OdataOption, pagination?: Pagination, grid?: any): void {
5969
this._grid = grid;
6070
const mergedOptions = { ...this.defaultOptions, ...options };

src/app/modules/angular-slickgrid/services/grid.service.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@ export class GridService {
3636
this._dataView = dataView;
3737
}
3838

39+
/** Clear all Filters & Sorts */
40+
clearAllFiltersAndSorts() {
41+
// call both clear Filters & Sort but only trigger the last one to avoid sending multiple backend queries
42+
if (this.sortService && this.sortService.clearSorting) {
43+
this.sortService.clearSorting(false); // skip event trigger on this one
44+
}
45+
if (this.filterService && this.filterService.clearFilters) {
46+
this.filterService.clearFilters();
47+
}
48+
}
49+
3950
/**
4051
* From a SlickGrid Event triggered get the Column Definition and Item Data Context
4152
*

src/app/modules/angular-slickgrid/services/sort.service.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,26 +125,34 @@ export class SortService {
125125
});
126126
}
127127

128-
clearSorting() {
128+
clearSorting(triggerQueryEvent = true) {
129129
if (this._grid && this._gridOptions && this._dataView) {
130130
// remove any sort icons (this setSortColumns function call really does only that)
131131
this._grid.setSortColumns([]);
132132

133133
// we also need to trigger a sort change
134134
// for a backend grid, we will trigger a backend sort changed with an empty sort columns array
135135
// however for a local grid, we need to pass a sort column and so we will sort by the 1st column
136-
if (this._isBackendGrid) {
137-
this.onBackendSortChanged(undefined, { grid: this._grid, sortCols: [] });
138-
} else {
139-
if (this._columnDefinitions && Array.isArray(this._columnDefinitions)) {
140-
this.onLocalSortChanged(this._grid, this._dataView, new Array({sortAsc: true, sortCol: this._columnDefinitions[0] }));
136+
if (triggerQueryEvent) {
137+
if (this._isBackendGrid) {
138+
this.onBackendSortChanged(undefined, { grid: this._grid, sortCols: [] });
139+
} else {
140+
if (this._columnDefinitions && Array.isArray(this._columnDefinitions)) {
141+
this.onLocalSortChanged(this._grid, this._dataView, new Array({sortAsc: true, sortCol: this._columnDefinitions[0] }));
142+
}
143+
}
144+
} else if (this._isBackendGrid) {
145+
const backendService = this._gridOptions && this._gridOptions.backendServiceApi && this._gridOptions.backendServiceApi.service;
146+
if (backendService && backendService.clearSorters) {
147+
backendService.clearSorters();
141148
}
142149
}
143150
}
151+
144152
// set current sorter to empty & emit a sort changed event
145153
this._currentLocalSorters = [];
146154

147-
// emit an event when filters are all cleared
155+
// emit an event when sorts are all cleared
148156
this.onSortCleared.next(true);
149157
}
150158

@@ -221,7 +229,7 @@ export class SortService {
221229
const columnSortObj = sortColumns[i];
222230
if (columnSortObj && columnSortObj.sortCol) {
223231
const sortDirection = columnSortObj.sortAsc ? SortDirectionNumber.asc : SortDirectionNumber.desc;
224-
const sortField = columnSortObj.sortCol.queryField || columnSortObj.sortCol.queryFieldFilter || columnSortObj.sortCol.field;
232+
const sortField = columnSortObj.sortCol.queryField || columnSortObj.sortCol.queryFieldSorter || columnSortObj.sortCol.field;
225233
const fieldType = columnSortObj.sortCol.type || FieldType.string;
226234
let value1 = dataRow1[sortField];
227235
let value2 = dataRow2[sortField];

0 commit comments

Comments
 (0)