Skip to content

Commit bd025ea

Browse files
committed
feat(paginator): expose previousPageIndex inside PageEvent
* 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 edb57f9 commit bd025ea

File tree

2 files changed

+64
-38
lines changed

2 files changed

+64
-38
lines changed

src/lib/paginator/paginator.spec.ts

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {async, ComponentFixture, TestBed, inject} 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
});
@@ -163,7 +169,10 @@ describe('MatPaginator', () => {
163169
dispatchMouseEvent(getLastButton(fixture), 'click');
164170

165171
expect(paginator.pageIndex).toBe(9);
166-
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(9);
172+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
173+
previousPageIndex: 0,
174+
pageIndex: 9
175+
}));
167176
});
168177

169178
it('should be able to go to the first page via the first page button', () => {
@@ -174,7 +183,10 @@ describe('MatPaginator', () => {
174183
dispatchMouseEvent(getFirstButton(fixture), 'click');
175184

176185
expect(paginator.pageIndex).toBe(0);
177-
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(0);
186+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
187+
previousPageIndex: 3,
188+
pageIndex: 0
189+
}));
178190
});
179191

180192
it('should disable navigating to the next page if at last page', () => {
@@ -183,21 +195,21 @@ describe('MatPaginator', () => {
183195
expect(paginator.pageIndex).toBe(9);
184196
expect(paginator.hasNextPage()).toBe(false);
185197

186-
component.latestPageEvent = null;
198+
component.pageEvent.calls.reset();
187199
dispatchMouseEvent(getNextButton(fixture), 'click');
188200

189-
expect(component.latestPageEvent).toBe(null);
201+
expect(component.pageEvent).not.toHaveBeenCalled();
190202
expect(paginator.pageIndex).toBe(9);
191203
});
192204

193205
it('should disable navigating to the previous page if at first page', () => {
194206
expect(paginator.pageIndex).toBe(0);
195207
expect(paginator.hasPreviousPage()).toBe(false);
196208

197-
component.latestPageEvent = null;
209+
component.pageEvent.calls.reset();
198210
dispatchMouseEvent(getPreviousButton(fixture), 'click');
199211

200-
expect(component.latestPageEvent).toBe(null);
212+
expect(component.pageEvent).not.toHaveBeenCalled();
201213
expect(paginator.pageIndex).toBe(0);
202214
});
203215

@@ -264,35 +276,37 @@ describe('MatPaginator', () => {
264276
fixture.detectChanges();
265277

266278
// The first item of the page should be item with index 40
267-
let firstPageItemIndex: number | null = paginator.pageIndex * paginator.pageSize;
268-
expect(firstPageItemIndex).toBe(40);
279+
expect(paginator.pageIndex * paginator.pageSize).toBe(40);
269280

270281
// The first item on the page is now 25. Change the page size to 25 so that we should now be
271282
// on the second page where the top item is index 25.
283+
component.pageEvent.calls.reset();
272284
paginator._changePageSize(25);
273-
let paginationEvent = component.latestPageEvent;
274-
firstPageItemIndex = paginationEvent ?
275-
paginationEvent.pageIndex * paginationEvent.pageSize : null;
276-
expect(firstPageItemIndex).toBe(25);
277-
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(1);
285+
286+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
287+
pageIndex: 1,
288+
pageSize: 25
289+
}));
278290

279291
// The first item on the page is still 25. Change the page size to 8 so that we should now be
280292
// on the fourth page where the top item is index 24.
293+
component.pageEvent.calls.reset();
281294
paginator._changePageSize(8);
282-
paginationEvent = component.latestPageEvent;
283-
firstPageItemIndex = paginationEvent ?
284-
paginationEvent.pageIndex * paginationEvent.pageSize : null;
285-
expect(firstPageItemIndex).toBe(24);
286-
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(3);
295+
296+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
297+
pageIndex: 3,
298+
pageSize: 8
299+
}));
287300

288301
// The first item on the page is 24. Change the page size to 16 so that we should now be
289302
// on the first page where the top item is index 0.
303+
component.pageEvent.calls.reset();
290304
paginator._changePageSize(25);
291-
paginationEvent = component.latestPageEvent;
292-
firstPageItemIndex = paginationEvent ?
293-
paginationEvent.pageIndex * paginationEvent.pageSize : null;
294-
expect(firstPageItemIndex).toBe(0);
295-
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(0);
305+
306+
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
307+
pageIndex: 0,
308+
pageSize: 25
309+
}));
296310
});
297311

298312
it('should show a select only if there are multiple options', () => {
@@ -357,7 +371,7 @@ function getLastButton(fixture: ComponentFixture<any>) {
357371
[hidePageSize]="hidePageSize"
358372
[showFirstLastButtons]="showFirstLastButtons"
359373
[length]="length"
360-
(page)="latestPageEvent = $event">
374+
(page)="pageEvent($event)">
361375
</mat-paginator>
362376
`,
363377
})
@@ -368,8 +382,7 @@ class MatPaginatorApp {
368382
hidePageSize = false;
369383
showFirstLastButtons = false;
370384
length = 100;
371-
372-
latestPageEvent: PageEvent | null;
385+
pageEvent = jasmine.createSpy('page event');
373386

374387
@ViewChild(MatPaginator) paginator: MatPaginator;
375388

src/lib/paginator/paginator.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ export class PageEvent {
3232
/** The current page index. */
3333
pageIndex: number;
3434

35+
/** Index of the page that was selected previously. */
36+
previousPageIndex: number;
37+
3538
/** The current page size */
3639
pageSize: number;
3740

@@ -136,31 +139,39 @@ export class MatPaginator implements OnInit, OnDestroy {
136139
/** Advances to the next page if it exists. */
137140
nextPage(): void {
138141
if (!this.hasNextPage()) { return; }
142+
143+
const previousPageIndex = this.pageIndex;
139144
this.pageIndex++;
140-
this._emitPageEvent();
145+
this._emitPageEvent(previousPageIndex);
141146
}
142147

143148
/** Move back to the previous page if it exists. */
144149
previousPage(): void {
145150
if (!this.hasPreviousPage()) { return; }
151+
152+
const previousPageIndex = this.pageIndex;
146153
this.pageIndex--;
147-
this._emitPageEvent();
154+
this._emitPageEvent(previousPageIndex);
148155
}
149156

150157
/** Move to the first page if not already there. */
151158
firstPage(): void {
152159
// hasPreviousPage being false implies at the start
153160
if (!this.hasPreviousPage()) { return; }
161+
162+
const previousPageIndex = this.pageIndex;
154163
this.pageIndex = 0;
155-
this._emitPageEvent();
164+
this._emitPageEvent(previousPageIndex);
156165
}
157166

158167
/** Move to the last page if not already there. */
159168
lastPage(): void {
160169
// hasNextPage being false implies at the end
161170
if (!this.hasNextPage()) { return; }
171+
172+
const previousPageIndex = this.pageIndex;
162173
this.pageIndex = this.getNumberOfPages();
163-
this._emitPageEvent();
174+
this._emitPageEvent(previousPageIndex);
164175
}
165176

166177
/** Whether there is a previous page. */
@@ -192,10 +203,11 @@ export class MatPaginator implements OnInit, OnDestroy {
192203
// Current page needs to be updated to reflect the new page size. Navigate to the page
193204
// containing the previous page's first item.
194205
const startIndex = this.pageIndex * this.pageSize;
195-
this.pageIndex = Math.floor(startIndex / pageSize) || 0;
206+
const previousPageIndex = this.pageIndex;
196207

208+
this.pageIndex = Math.floor(startIndex / pageSize) || 0;
197209
this.pageSize = pageSize;
198-
this._emitPageEvent();
210+
this._emitPageEvent(previousPageIndex);
199211
}
200212

201213
/**
@@ -213,19 +225,20 @@ export class MatPaginator implements OnInit, OnDestroy {
213225
}
214226

215227
this._displayedPageSizeOptions = this.pageSizeOptions.slice();
216-
if (this._displayedPageSizeOptions.indexOf(this.pageSize) == -1) {
228+
229+
if (this._displayedPageSizeOptions.indexOf(this.pageSize) === -1) {
217230
this._displayedPageSizeOptions.push(this.pageSize);
218231
}
219232

220233
// Sort the numbers using a number-specific sort function.
221234
this._displayedPageSizeOptions.sort((a, b) => a - b);
222-
223235
this._changeDetectorRef.markForCheck();
224236
}
225237

226238
/** Emits an event notifying that a change of the paginator's properties has been triggered. */
227-
private _emitPageEvent() {
239+
private _emitPageEvent(previousPageIndex: number) {
228240
this.page.emit({
241+
previousPageIndex,
229242
pageIndex: this.pageIndex,
230243
pageSize: this.pageSize,
231244
length: this.length

0 commit comments

Comments
 (0)