-
-
Notifications
You must be signed in to change notification settings - Fork 19
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
feat(event): #24 add onGridStateChanged and onPaginationChanged events #28
Changes from 1 commit
dd71e8d
1a399ec
2a68caa
5ee0d8e
9cbbc7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import { GridStateChange } from './models/gridStateChange.interface'; | ||
// import 3rd party vendor libs | ||
import 'slickgrid/lib/jquery-ui-1.11.3'; | ||
import 'slickgrid/lib/jquery.event.drag-2.3.0'; | ||
|
@@ -30,7 +31,9 @@ import { | |
Column, | ||
FormElementType, | ||
GraphqlResult, | ||
GridOption | ||
GridOption, | ||
GridStateType, | ||
Pagination, | ||
} from './models/index'; | ||
import { | ||
ControlAndPluginService, | ||
|
@@ -56,6 +59,7 @@ const eventPrefix = 'sg'; | |
export class AureliaSlickgridCustomElement { | ||
private _dataset: any[]; | ||
private _eventHandler: any = new Slick.EventHandler(); | ||
gridStateSubscriber: Subscription; | ||
gridHeightString: string; | ||
gridWidthString: string; | ||
localeChangedSubscriber: Subscription; | ||
|
@@ -158,11 +162,13 @@ export class AureliaSlickgridCustomElement { | |
this.dataview = []; | ||
this._eventHandler.unsubscribeAll(); | ||
this.controlAndPluginService.dispose(); | ||
this.gridEventService.dispose(); | ||
this.filterService.dispose(); | ||
this.gridEventService.dispose(); | ||
this.gridStateService.dispose(); | ||
this.resizer.dispose(); | ||
this.sortService.dispose(); | ||
this.grid.destroy(); | ||
this.gridStateSubscriber.dispose(); | ||
this.localeChangedSubscriber.dispose(); | ||
this.ea.publish('onAfterGridDestroyed', true); | ||
this.elm.dispatchEvent(new CustomEvent(`${eventPrefix}-on-after-grid-destroyed`, { | ||
|
@@ -258,6 +264,7 @@ export class AureliaSlickgridCustomElement { | |
} | ||
} | ||
|
||
// expose all Slick Grid Events through dispatch | ||
for (const prop in grid) { | ||
if (grid.hasOwnProperty(prop) && prop.startsWith('on')) { | ||
this._eventHandler.subscribe(grid[prop], (e: any, args: any) => { | ||
|
@@ -272,6 +279,7 @@ export class AureliaSlickgridCustomElement { | |
} | ||
} | ||
|
||
// expose all Slick DataView Events through dispatch | ||
for (const prop in dataView) { | ||
if (dataView.hasOwnProperty(prop) && prop.startsWith('on')) { | ||
this._eventHandler.subscribe(dataView[prop], (e: any, args: any) => { | ||
|
@@ -286,6 +294,14 @@ export class AureliaSlickgridCustomElement { | |
} | ||
} | ||
|
||
// expose GridState Service changes event through dispatch | ||
this.gridStateSubscriber = this.ea.subscribe('gridStateService:changed', (gridStateChange: GridStateChange) => { | ||
this.elm.dispatchEvent(new CustomEvent(`on-grid-state-service-changed`, { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment about the |
||
bubbles: true, | ||
detail: gridStateChange | ||
})); | ||
}); | ||
|
||
// on cell click, mainly used with the columnDef.action callback | ||
this.gridEventService.attachOnCellChange(grid, this.gridOptions, dataView); | ||
this.gridEventService.attachOnClick(grid, this.gridOptions, dataView); | ||
|
@@ -381,6 +397,13 @@ export class AureliaSlickgridCustomElement { | |
return $.extend(true, {}, GlobalGridOptions, this.gridOptions); | ||
} | ||
|
||
paginationChanged(pagination: Pagination) { | ||
this.ea.publish('gridStateService:changed', { | ||
change: { newValues: pagination, type: GridStateType.pagination }, | ||
gridState: this.gridStateService.getCurrentGridState() | ||
}); | ||
} | ||
|
||
/** | ||
* When dataset changes, we need to refresh the entire grid UI & possibly resize it as well | ||
* @param dataset | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { CurrentFilter, CurrentSorter, GridState, GridStateType, Pagination } from './../models/index'; | ||
|
||
export interface GridStateChange { | ||
/** Changes that were triggered */ | ||
change?: { | ||
newValues: CurrentFilter[] | CurrentSorter[] | Pagination; | ||
type: GridStateType; | ||
}; | ||
|
||
/** Current grid state */ | ||
gridState?: GridState; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export enum GridStateType { | ||
filter = 'filter', | ||
pagination = 'pagination', | ||
sorter = 'sorter' | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,19 +21,18 @@ import * as $ from 'jquery'; | |
// using external non-typed js libraries | ||
declare var Slick: any; | ||
|
||
@inject(FilterFactory) | ||
@inject(EventAggregator, FilterFactory) | ||
export class FilterService { | ||
private _eventHandler = new Slick.EventHandler(); | ||
private _subscriber: SlickEvent = new Slick.Event(); | ||
private _slickSubscriber: SlickEvent; | ||
private _filters: any[] = []; | ||
private _columnFilters: ColumnFilters = {}; | ||
private _dataView: any; | ||
private _grid: any; | ||
private _gridOptions: GridOption; | ||
private _onFilterChangedOptions: any; | ||
onFilterChanged = new EventAggregator(); | ||
|
||
constructor(private filterFactory: FilterFactory) { } | ||
constructor(private ea: EventAggregator, private filterFactory: FilterFactory) { } | ||
|
||
init(grid: any, gridOptions: GridOption, columnDefinitions: Column[]): void { | ||
this._grid = grid; | ||
|
@@ -47,18 +46,21 @@ export class FilterService { | |
*/ | ||
attachBackendOnFilter(grid: any, options: GridOption) { | ||
this._filters = []; | ||
this.emitFilterChangedBy('remote'); | ||
this._slickSubscriber = new Slick.Event(); | ||
|
||
this._subscriber = new Slick.Event(); | ||
this._subscriber.subscribe(this.attachBackendOnFilterSubscribe); | ||
// subscribe to the SlickGrid event and call the backend execution | ||
// we also need to add our filter service (with .bind) to the callback function (which is outside of this service) | ||
// the callback doesn't have access to this service, so we need to bind it | ||
const self = this; | ||
this._slickSubscriber.subscribe(this.attachBackendOnFilterSubscribe.bind(this, self)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since you are binding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You only need There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok will give that a try a bit later There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you were right about this, I didn't know that simply doing the |
||
|
||
// subscribe to SlickGrid onHeaderRowCellRendered event to create filter template | ||
this._eventHandler.subscribe(grid.onHeaderRowCellRendered, (e: Event, args: any) => { | ||
this.addFilterTemplateToHeaderRow(args); | ||
}); | ||
} | ||
|
||
async attachBackendOnFilterSubscribe(event: Event, args: any) { | ||
async attachBackendOnFilterSubscribe(self: FilterService, event: Event, args: any) { | ||
if (!args || !args.grid) { | ||
throw new Error('Something went wrong when trying to attach the "attachBackendOnFilterSubscribe(event, args)" function, it seems that "args" is not populated correctly'); | ||
} | ||
|
@@ -77,6 +79,9 @@ export class FilterService { | |
// call the service to get a query back | ||
const query = await backendApi.service.onFilterChanged(event, args); | ||
|
||
// emit an onFilterChanged event | ||
self.emitFilterChanged('remote'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when |
||
|
||
// await for the Promise to resolve the data | ||
const processResult = await backendApi.process(query); | ||
|
||
|
@@ -91,6 +96,34 @@ export class FilterService { | |
} | ||
} | ||
|
||
/** | ||
* Attach a local filter hook to the grid | ||
* @param grid SlickGrid Grid object | ||
* @param gridOptions Grid Options object | ||
* @param dataView | ||
*/ | ||
attachLocalOnFilter(grid: any, options: GridOption, dataView: any) { | ||
this._filters = []; | ||
this._dataView = dataView; | ||
this._slickSubscriber = new Slick.Event(); | ||
|
||
dataView.setFilterArgs({ columnFilters: this._columnFilters, grid: this._grid }); | ||
dataView.setFilter(this.customLocalFilter.bind(this, dataView)); | ||
|
||
this._slickSubscriber.subscribe((e: any, args: any) => { | ||
const columnId = args.columnId; | ||
if (columnId != null) { | ||
dataView.refresh(); | ||
} | ||
this.emitFilterChanged('local'); | ||
}); | ||
|
||
// subscribe to SlickGrid onHeaderRowCellRendered event to create filter template | ||
this._eventHandler.subscribe(grid.onHeaderRowCellRendered, (e: Event, args: any) => { | ||
this.addFilterTemplateToHeaderRow(args); | ||
}); | ||
} | ||
|
||
/** Clear the search filters (below the column titles) */ | ||
clearFilters() { | ||
this._filters.forEach((filter, index) => { | ||
|
@@ -116,34 +149,6 @@ export class FilterService { | |
} | ||
} | ||
|
||
/** | ||
* Attach a local filter hook to the grid | ||
* @param grid SlickGrid Grid object | ||
* @param gridOptions Grid Options object | ||
* @param dataView | ||
*/ | ||
attachLocalOnFilter(grid: any, options: GridOption, dataView: any) { | ||
this._dataView = dataView; | ||
this._filters = []; | ||
this.emitFilterChangedBy('local'); | ||
|
||
dataView.setFilterArgs({ columnFilters: this._columnFilters, grid: this._grid }); | ||
dataView.setFilter(this.customLocalFilter.bind(this, dataView)); | ||
|
||
this._subscriber = new Slick.Event(); | ||
this._subscriber.subscribe((e: any, args: any) => { | ||
const columnId = args.columnId; | ||
if (columnId != null) { | ||
dataView.refresh(); | ||
} | ||
}); | ||
|
||
// subscribe to SlickGrid onHeaderRowCellRendered event to create filter template | ||
this._eventHandler.subscribe(grid.onHeaderRowCellRendered, (e: Event, args: any) => { | ||
this.addFilterTemplateToHeaderRow(args); | ||
}); | ||
} | ||
|
||
customLocalFilter(dataView: any, item: any, args: any) { | ||
for (const columnId of Object.keys(args.columnFilters)) { | ||
const columnFilter = args.columnFilters[columnId]; | ||
|
@@ -236,8 +241,8 @@ export class FilterService { | |
this._eventHandler.unsubscribeAll(); | ||
|
||
// unsubscribe local event | ||
if (this._subscriber && typeof this._subscriber.unsubscribe === 'function') { | ||
this._subscriber.unsubscribe(); | ||
if (this._slickSubscriber && typeof this._slickSubscriber.unsubscribe === 'function') { | ||
this._slickSubscriber.unsubscribe(); | ||
} | ||
} | ||
|
||
|
@@ -302,7 +307,7 @@ export class FilterService { | |
}; | ||
} | ||
|
||
this.triggerEvent(this._subscriber, { | ||
this.triggerEvent(this._slickSubscriber, { | ||
columnId, | ||
columnDef: args.columnDef || null, | ||
columnFilters: this._columnFilters, | ||
|
@@ -378,12 +383,21 @@ export class FilterService { | |
} | ||
|
||
/** | ||
* A simple function that is attached to the subscriber and emit a change when the sort is called. | ||
* A simple function that will be called to emit a change when a filter changes. | ||
* Other services, like Pagination, can then subscribe to it. | ||
* @param {string} sender | ||
* @param sender | ||
*/ | ||
emitFilterChangedBy(sender: string) { | ||
this._subscriber.subscribe(() => this.onFilterChanged.publish('filterService:changed', `onFilterChanged by ${sender}`)); | ||
emitFilterChanged(sender: 'local' | 'remote') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the let currentFilters: CurrentFilter[] = [];
if (sender === 'remote') {
const backendService = this._gridOptions.backendServiceApi.service;
if (backendService && backendService.getCurrentFilters) {
currentFilters = backendService.getCurrentFilters() as CurrentFilter[];
}
} else {
currentFilters = this.getCurrentLocalFilters();
}
this.ea.publish('filterService:filterChanged', currentFilters); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm playing it safe and it's still better to see what is acceptable right from the argument |
||
if (sender === 'remote') { | ||
let currentFilters: CurrentFilter[] = []; | ||
const backendService = this._gridOptions.backendServiceApi.service; | ||
if (backendService && backendService.getCurrentFilters) { | ||
currentFilters = backendService.getCurrentFilters() as CurrentFilter[]; | ||
} | ||
this.ea.publish('filterService:filterChanged', currentFilters); | ||
} else if (sender === 'local') { | ||
this.ea.publish('filterService:filterChanged', this.getCurrentLocalFilters()); | ||
} | ||
} | ||
|
||
/** | ||
|
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.
see comment about using the
eventPrefix