Skip to content

Commit 22ed10f

Browse files
committed
feat($browser): Added events to provide the data after it is filtered and after it is sorted.
Added new events to the ngTableEventsChannel that fire when the ngTableDefaultGetData filters and sorts the data. This is usefull when you want to try to export only the filtered data or when you want to make some real time statistics over the data that is beeing filtered.
1 parent 66f8761 commit 22ed10f

File tree

4 files changed

+148
-5
lines changed

4 files changed

+148
-5
lines changed

src/core/ngTableDefaultGetData.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import * as ng1 from 'angular';
10-
import { IDefaultGetDataProvider, IDefaultGetData, IFilterFunc, INgTableParams } from './public-interfaces';
10+
import { IDefaultGetDataProvider, IDefaultGetData, IFilterFunc, INgTableParams, IEventsChannel } from './public-interfaces';
1111

1212
/**
1313
* Allows for the configuration of the ngTableDefaultGetData service.
@@ -26,22 +26,24 @@ import { IDefaultGetDataProvider, IDefaultGetData, IFilterFunc, INgTableParams }
2626
export class ngTableDefaultGetDataProvider implements IDefaultGetDataProvider {
2727
filterFilterName = 'filter';
2828
sortingFilterName = 'orderBy';
29-
$get: ($filter: ng1.IFilterService) => IDefaultGetData<any>;
29+
$get: ($filter: ng1.IFilterService, ngTableEventsChannel: IEventsChannel) => IDefaultGetData<any>;
3030
constructor() {
3131
var provider = this;
3232
this.$get = ngTableDefaultGetData;
3333

34-
ngTableDefaultGetData.$inject = ['$filter'];
34+
ngTableDefaultGetData.$inject = ['$filter', 'ngTableEventsChannel'];
3535

3636
/**
3737
* Implementation of the {@link IDefaultGetData IDefaultGetData} interface
3838
*
3939
* @ngdoc service
4040
*/
41-
function ngTableDefaultGetData<T>($filter: ng1.IFilterService): IDefaultGetData<T> {
41+
function ngTableDefaultGetData<T>($filter: ng1.IFilterService, ngTableEventsChannel: IEventsChannel): IDefaultGetData<T> {
4242

4343
var defaultDataOptions = { applyFilter: true, applySort: true, applyPaging: true };
4444

45+
var self = this;
46+
4547
(getData as IDefaultGetData<T>).applyPaging = applyPaging;
4648
(getData as IDefaultGetData<T>).getFilterFn = getFilterFn;
4749
(getData as IDefaultGetData<T>).getOrderByFn = getOrderByFn;
@@ -96,7 +98,11 @@ export class ngTableDefaultGetDataProvider implements IDefaultGetDataProvider {
9698
var options = ng1.extend({}, defaultDataOptions, params.settings().dataOptions);
9799

98100
var fData = options.applyFilter ? applyFilter(data, params) : data;
101+
ngTableEventsChannel.publishAfterDataFiltered(self, params, fData);
102+
99103
var orderedData = options.applySort ? applySort(fData, params) : fData;
104+
ngTableEventsChannel.publishAfterDataSorted(self, params,orderedData);
105+
100106
return options.applyPaging ? applyPaging(orderedData, params) : orderedData;
101107
}
102108

src/core/ngTableEventsChannel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export function ngTableEventsChannel($rootScope: ng1.IRootScopeService): IEvents
2222
events = addTableParamsEvent('afterReloadData', events);
2323
events = addTableParamsEvent('datasetChanged', events);
2424
events = addTableParamsEvent('pagesChanged', events);
25+
events = addTableParamsEvent('afterDataFiltered', events);
26+
events = addTableParamsEvent('afterDataSorted', events);
2527
return events as IEventsChannel;
2628

2729
//////////

src/core/public-interfaces.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,18 @@ export interface IEventSelectorFunc {
545545
export interface IPagesChangedListener {
546546
(publisher: INgTableParams<any>, newPages: IPageButton[], oldPages: IPageButton[]): any
547547
}
548+
/**
549+
* Signature of the event hander that is registered to receive the *afterDataFiltered* event
550+
*/
551+
export interface IAfterDataFilteredListener<T> {
552+
(publisher: IDefaultGetData<T>, params: INgTableParams<T>, newData: DataResult<T>[] ): any
553+
}
554+
/**
555+
* Signature of the event hander that is registered to receive the *afterDataSorted* event
556+
*/
557+
export interface IAfterDataSortedListener<T> {
558+
(publisher: IDefaultGetData<T>, params: INgTableParams<T>, newData: DataResult<T>[] ): any
559+
}
548560

549561
/**
550562
* Signature of the function used to explicitly unregister an event handler so that it stops
@@ -647,9 +659,50 @@ export interface IEventsChannel {
647659
* @return a unregistration function that when called will unregister the `listener`
648660
*/
649661
onPagesChanged<T>(listener: IPagesChangedListener, eventFilter?: EventSelector<T>): IUnregistrationFunc;
662+
/**
663+
* Subscribe to receive notification whenever a `ngTableDefaultGetData` instance filters data
664+
* Optionally supply an `eventFilter` to restrict which events that should trigger the `listener` to be called.
665+
*
666+
* @param listener the function that will be called when the event fires
667+
* @param scope the angular `$scope` that will limit the lifetime of the event subscription
668+
* @param eventFilter either the specific `IDefaultGetData` instance you want to receive events for or a predicate function that should return true to receive the event
669+
* @return a unregistration function that when called will unregister the `listener`
670+
*/
671+
onAfterDataFiltered<T>(listener: IAfterDataFilteredListener<T>, scope: IScope, eventFilter?: EventSelector<T> ): IUnregistrationFunc;
672+
/**
673+
* Subscribe to receive notification whenever a `ngTableDefaultGetData` instance filters data
674+
* Optionally supply an `eventFilter` to restrict which events that should trigger the `listener` to be called.
675+
*
676+
* @param listener the function that will be called when the event fires
677+
* @param eventFilter either the specific `IDefaultGetData` instance you want to receive events for or a predicate function that should return true to receive the event
678+
* @return a unregistration function that when called will unregister the `listener`
679+
*/
680+
onAfterDataFiltered<T>(listener: IAfterDataFilteredListener<T>, eventFilter?: EventSelector<T> ): IUnregistrationFunc;
681+
/**
682+
* Subscribe to receive notification whenever a `ngTableDefaultGetData` instance orders data
683+
* Optionally supply an `eventFilter` to restrict which events that should trigger the `listener` to be called.
684+
*
685+
* @param listener the function that will be called when the event fires
686+
* @param scope the angular `$scope` that will limit the lifetime of the event subscription
687+
* @param eventFilter either the specific `IDefaultGetData` instance you want to receive events for or a predicate function that should return true to receive the event
688+
* @return a unregistration function that when called will unregister the `listener`
689+
*/
690+
onAfterDataSorted<T>(listener: IAfterDataSortedListener<T>, scope: IScope, eventFilter?: EventSelector<T> ): IUnregistrationFunc;
691+
/**
692+
* Subscribe to receive notification whenever a `ngTableDefaultGetData` instance orders data
693+
* Optionally supply an `eventFilter` to restrict which events that should trigger the `listener` to be called.
694+
*
695+
* @param listener the function that will be called when the event fires
696+
* @param eventFilter either the specific `IDefaultGetData` instance you want to receive events for or a predicate function that should return true to receive the event
697+
* @return a unregistration function that when called will unregister the `listener`
698+
*/
699+
onAfterDataSorted<T>(listener: IAfterDataSortedListener<T>, eventFilter?: EventSelector<T> ): IUnregistrationFunc;
650700

651701
publishAfterCreated<T>(publisher: INgTableParams<T>): void;
652702
publishAfterReloadData<T>(publisher: INgTableParams<T>, newData: T[], oldData: T[]): void;
653703
publishDatasetChanged<T>(publisher: INgTableParams<T>, newDataset: T[], oldDataset: T[]): void;
654704
publishPagesChanged<T>(publisher: INgTableParams<T>, newPages: IPageButton[], oldPages: IPageButton[]): void;
655-
}
705+
publishAfterDataFiltered<T>(publisher: IDefaultGetData<T>, params: INgTableParams<T>, newData: T[]): void;
706+
publishAfterDataSorted<T>(publisher: IDefaultGetData<T>, params: INgTableParams<T>, newData: T[]): void;
707+
}
708+

test/tableParamsSpec.spec.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,5 +2159,87 @@ describe('NgTableParams', () => {
21592159
expect(events[1]).toEqual('datasetChanged');
21602160
});
21612161
});
2162+
2163+
describe('afterDataFiltered', () => {
2164+
it('should fire when a reload completes - no filter', () => {
2165+
// given
2166+
ngTableEventsChannel.onAfterDataFiltered((getData, params, newVal) => {
2167+
actualPublisher = params;
2168+
actualEventArgs = [newVal];
2169+
});
2170+
var data = [1,2,3];
2171+
var params = createNgTableParams({ count: 5 }, { counts: [5, 10], dataset: data });
2172+
2173+
// when
2174+
params.reload();
2175+
scope.$digest();
2176+
2177+
// then
2178+
expect(actualPublisher).toBe(params);
2179+
expect(actualEventArgs).toEqual([data]);
2180+
});
2181+
2182+
it('should fire when a reload completes and the data is filtered', () => {
2183+
// given
2184+
ngTableEventsChannel.onAfterDataFiltered((getData, params, newVal) => {
2185+
actualPublisher = params;
2186+
actualEventArgs = [newVal];
2187+
});
2188+
2189+
var initialDs = [10, 10, 101, 5];
2190+
var expectedDs = [10, 10, 101]; // when filtered with "10"
2191+
var params = createNgTableParams({ dataset: initialDs });
2192+
params.filter({ $: "10" });
2193+
2194+
// when
2195+
params.reload();
2196+
scope.$digest();
2197+
2198+
// then
2199+
expect(actualPublisher).toBe(params);
2200+
expect(actualEventArgs).toEqual([expectedDs]);
2201+
});
2202+
});
2203+
2204+
describe('afterDataSorted', () => {
2205+
it('should fire when a reload completes - no order', () => {
2206+
// given
2207+
ngTableEventsChannel.onAfterDataSorted((getData, params, newVal) => {
2208+
actualPublisher = params;
2209+
actualEventArgs = [newVal];
2210+
});
2211+
var data = [1,2,3];
2212+
var params = createNgTableParams({ count: 5 }, { counts: [5, 10], dataset: data });
2213+
2214+
// when
2215+
params.reload();
2216+
scope.$digest();
2217+
2218+
// then
2219+
expect(actualPublisher).toBe(params);
2220+
expect(actualEventArgs).toEqual([data]);
2221+
});
2222+
2223+
it('should fire when a reload completes and the data is filtered', () => {
2224+
// given
2225+
ngTableEventsChannel.onAfterDataSorted((getData, params, newVal) => {
2226+
actualPublisher = params;
2227+
actualEventArgs = [newVal];
2228+
});
2229+
2230+
var initialDs = [10, 10, 101, 5];
2231+
var expectedDs = [10, 10, 101]; // when filtered with "10"
2232+
var params = createNgTableParams({ dataset: initialDs });
2233+
params.filter({ $: "10" });
2234+
2235+
// when
2236+
params.reload();
2237+
scope.$digest();
2238+
2239+
// then
2240+
expect(actualPublisher).toBe(params);
2241+
expect(actualEventArgs).toEqual([expectedDs]);
2242+
});
2243+
});
21622244
})
21632245
});

0 commit comments

Comments
 (0)