Skip to content

Commit 85039ca

Browse files
crisbetoandrewseguin
authored andcommitted
feat(paginator): expose previousPageIndex inside PageEvent (#10759)
* Exposes the previous page index inside the object that is emitted by the `page` event. * Reworks the `page` event tests to use a spy rather than saving the last result to the test component. Fixes #10758.
1 parent 848fe58 commit 85039ca

File tree

2 files changed

+67
-38
lines changed

2 files changed

+67
-38
lines changed

src/lib/paginator/paginator.spec.ts

+42-29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {async, ComponentFixture, TestBed, inject, tick, fakeAsync} from '@angular/core/testing';
22
import {MatPaginatorModule} from './index';
3-
import {MatPaginator, PageEvent} from './paginator';
3+
import {MatPaginator} from './paginator';
44
import {Component, ViewChild} from '@angular/core';
55
import {MatPaginatorIntl} from './paginator-intl';
66
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
@@ -111,7 +111,10 @@ describe('MatPaginator', () => {
111111
dispatchMouseEvent(getNextButton(fixture), 'click');
112112

113113
expect(paginator.pageIndex).toBe(1);
114-
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(1);
114+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
115+
previousPageIndex: 0,
116+
pageIndex: 1
117+
}));
115118
});
116119

117120
it('should be able to go to the previous page', () => {
@@ -122,7 +125,10 @@ describe('MatPaginator', () => {
122125
dispatchMouseEvent(getPreviousButton(fixture), 'click');
123126

124127
expect(paginator.pageIndex).toBe(0);
125-
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(0);
128+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
129+
previousPageIndex: 1,
130+
pageIndex: 0
131+
}));
126132
});
127133
});
128134

@@ -169,7 +175,10 @@ describe('MatPaginator', () => {
169175
dispatchMouseEvent(getLastButton(fixture), 'click');
170176

171177
expect(paginator.pageIndex).toBe(9);
172-
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(9);
178+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
179+
previousPageIndex: 0,
180+
pageIndex: 9
181+
}));
173182
});
174183

175184
it('should be able to go to the first page via the first page button', () => {
@@ -180,7 +189,10 @@ describe('MatPaginator', () => {
180189
dispatchMouseEvent(getFirstButton(fixture), 'click');
181190

182191
expect(paginator.pageIndex).toBe(0);
183-
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(0);
192+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
193+
previousPageIndex: 3,
194+
pageIndex: 0
195+
}));
184196
});
185197

186198
it('should disable navigating to the next page if at last page', () => {
@@ -189,21 +201,21 @@ describe('MatPaginator', () => {
189201
expect(paginator.pageIndex).toBe(9);
190202
expect(paginator.hasNextPage()).toBe(false);
191203

192-
component.latestPageEvent = null;
204+
component.pageEvent.calls.reset();
193205
dispatchMouseEvent(getNextButton(fixture), 'click');
194206

195-
expect(component.latestPageEvent).toBe(null);
207+
expect(component.pageEvent).not.toHaveBeenCalled();
196208
expect(paginator.pageIndex).toBe(9);
197209
});
198210

199211
it('should disable navigating to the previous page if at first page', () => {
200212
expect(paginator.pageIndex).toBe(0);
201213
expect(paginator.hasPreviousPage()).toBe(false);
202214

203-
component.latestPageEvent = null;
215+
component.pageEvent.calls.reset();
204216
dispatchMouseEvent(getPreviousButton(fixture), 'click');
205217

206-
expect(component.latestPageEvent).toBe(null);
218+
expect(component.pageEvent).not.toHaveBeenCalled();
207219
expect(paginator.pageIndex).toBe(0);
208220
});
209221

@@ -270,35 +282,37 @@ describe('MatPaginator', () => {
270282
fixture.detectChanges();
271283

272284
// The first item of the page should be item with index 40
273-
let firstPageItemIndex: number | null = paginator.pageIndex * paginator.pageSize;
274-
expect(firstPageItemIndex).toBe(40);
285+
expect(paginator.pageIndex * paginator.pageSize).toBe(40);
275286

276287
// The first item on the page is now 25. Change the page size to 25 so that we should now be
277288
// on the second page where the top item is index 25.
289+
component.pageEvent.calls.reset();
278290
paginator._changePageSize(25);
279-
let paginationEvent = component.latestPageEvent;
280-
firstPageItemIndex = paginationEvent ?
281-
paginationEvent.pageIndex * paginationEvent.pageSize : null;
282-
expect(firstPageItemIndex).toBe(25);
283-
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(1);
291+
292+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
293+
pageIndex: 1,
294+
pageSize: 25
295+
}));
284296

285297
// The first item on the page is still 25. Change the page size to 8 so that we should now be
286298
// on the fourth page where the top item is index 24.
299+
component.pageEvent.calls.reset();
287300
paginator._changePageSize(8);
288-
paginationEvent = component.latestPageEvent;
289-
firstPageItemIndex = paginationEvent ?
290-
paginationEvent.pageIndex * paginationEvent.pageSize : null;
291-
expect(firstPageItemIndex).toBe(24);
292-
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(3);
301+
302+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
303+
pageIndex: 3,
304+
pageSize: 8
305+
}));
293306

294307
// The first item on the page is 24. Change the page size to 16 so that we should now be
295308
// on the first page where the top item is index 0.
309+
component.pageEvent.calls.reset();
296310
paginator._changePageSize(25);
297-
paginationEvent = component.latestPageEvent;
298-
firstPageItemIndex = paginationEvent ?
299-
paginationEvent.pageIndex * paginationEvent.pageSize : null;
300-
expect(firstPageItemIndex).toBe(0);
301-
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(0);
311+
312+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
313+
pageIndex: 0,
314+
pageSize: 25
315+
}));
302316
});
303317

304318
it('should show a select only if there are multiple options', () => {
@@ -363,7 +377,7 @@ function getLastButton(fixture: ComponentFixture<any>) {
363377
[hidePageSize]="hidePageSize"
364378
[showFirstLastButtons]="showFirstLastButtons"
365379
[length]="length"
366-
(page)="latestPageEvent = $event">
380+
(page)="pageEvent($event)">
367381
</mat-paginator>
368382
`,
369383
})
@@ -374,8 +388,7 @@ class MatPaginatorApp {
374388
hidePageSize = false;
375389
showFirstLastButtons = false;
376390
length = 100;
377-
378-
latestPageEvent: PageEvent | null;
391+
pageEvent = jasmine.createSpy('page event');
379392

380393
@ViewChild(MatPaginator) paginator: MatPaginator;
381394

src/lib/paginator/paginator.ts

+25-9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ export class PageEvent {
3333
/** The current page index. */
3434
pageIndex: number;
3535

36+
/**
37+
* Index of the page that was selected previously.
38+
* @deletion-target 7.0.0 To be made into a required property.
39+
*/
40+
previousPageIndex?: number;
41+
3642
/** The current page size */
3743
pageSize: number;
3844

@@ -144,31 +150,39 @@ export class MatPaginator extends _MatPaginatorBase implements OnInit, OnDestroy
144150
/** Advances to the next page if it exists. */
145151
nextPage(): void {
146152
if (!this.hasNextPage()) { return; }
153+
154+
const previousPageIndex = this.pageIndex;
147155
this.pageIndex++;
148-
this._emitPageEvent();
156+
this._emitPageEvent(previousPageIndex);
149157
}
150158

151159
/** Move back to the previous page if it exists. */
152160
previousPage(): void {
153161
if (!this.hasPreviousPage()) { return; }
162+
163+
const previousPageIndex = this.pageIndex;
154164
this.pageIndex--;
155-
this._emitPageEvent();
165+
this._emitPageEvent(previousPageIndex);
156166
}
157167

158168
/** Move to the first page if not already there. */
159169
firstPage(): void {
160170
// hasPreviousPage being false implies at the start
161171
if (!this.hasPreviousPage()) { return; }
172+
173+
const previousPageIndex = this.pageIndex;
162174
this.pageIndex = 0;
163-
this._emitPageEvent();
175+
this._emitPageEvent(previousPageIndex);
164176
}
165177

166178
/** Move to the last page if not already there. */
167179
lastPage(): void {
168180
// hasNextPage being false implies at the end
169181
if (!this.hasNextPage()) { return; }
182+
183+
const previousPageIndex = this.pageIndex;
170184
this.pageIndex = this.getNumberOfPages();
171-
this._emitPageEvent();
185+
this._emitPageEvent(previousPageIndex);
172186
}
173187

174188
/** Whether there is a previous page. */
@@ -200,10 +214,11 @@ export class MatPaginator extends _MatPaginatorBase implements OnInit, OnDestroy
200214
// Current page needs to be updated to reflect the new page size. Navigate to the page
201215
// containing the previous page's first item.
202216
const startIndex = this.pageIndex * this.pageSize;
203-
this.pageIndex = Math.floor(startIndex / pageSize) || 0;
217+
const previousPageIndex = this.pageIndex;
204218

219+
this.pageIndex = Math.floor(startIndex / pageSize) || 0;
205220
this.pageSize = pageSize;
206-
this._emitPageEvent();
221+
this._emitPageEvent(previousPageIndex);
207222
}
208223

209224
/**
@@ -221,19 +236,20 @@ export class MatPaginator extends _MatPaginatorBase implements OnInit, OnDestroy
221236
}
222237

223238
this._displayedPageSizeOptions = this.pageSizeOptions.slice();
224-
if (this._displayedPageSizeOptions.indexOf(this.pageSize) == -1) {
239+
240+
if (this._displayedPageSizeOptions.indexOf(this.pageSize) === -1) {
225241
this._displayedPageSizeOptions.push(this.pageSize);
226242
}
227243

228244
// Sort the numbers using a number-specific sort function.
229245
this._displayedPageSizeOptions.sort((a, b) => a - b);
230-
231246
this._changeDetectorRef.markForCheck();
232247
}
233248

234249
/** Emits an event notifying that a change of the paginator's properties has been triggered. */
235-
private _emitPageEvent() {
250+
private _emitPageEvent(previousPageIndex: number) {
236251
this.page.emit({
252+
previousPageIndex,
237253
pageIndex: this.pageIndex,
238254
pageSize: this.pageSize,
239255
length: this.length

0 commit comments

Comments
 (0)