Skip to content

Commit bec262f

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 bec262f

File tree

3 files changed

+69
-40
lines changed

3 files changed

+69
-40
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: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ export class PageEvent {
3232
/** The current page index. */
3333
pageIndex: number;
3434

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

@@ -136,31 +142,39 @@ export class MatPaginator implements OnInit, OnDestroy {
136142
/** Advances to the next page if it exists. */
137143
nextPage(): void {
138144
if (!this.hasNextPage()) { return; }
145+
146+
const previousPageIndex = this.pageIndex;
139147
this.pageIndex++;
140-
this._emitPageEvent();
148+
this._emitPageEvent(previousPageIndex);
141149
}
142150

143151
/** Move back to the previous page if it exists. */
144152
previousPage(): void {
145153
if (!this.hasPreviousPage()) { return; }
154+
155+
const previousPageIndex = this.pageIndex;
146156
this.pageIndex--;
147-
this._emitPageEvent();
157+
this._emitPageEvent(previousPageIndex);
148158
}
149159

150160
/** Move to the first page if not already there. */
151161
firstPage(): void {
152162
// hasPreviousPage being false implies at the start
153163
if (!this.hasPreviousPage()) { return; }
164+
165+
const previousPageIndex = this.pageIndex;
154166
this.pageIndex = 0;
155-
this._emitPageEvent();
167+
this._emitPageEvent(previousPageIndex);
156168
}
157169

158170
/** Move to the last page if not already there. */
159171
lastPage(): void {
160172
// hasNextPage being false implies at the end
161173
if (!this.hasNextPage()) { return; }
174+
175+
const previousPageIndex = this.pageIndex;
162176
this.pageIndex = this.getNumberOfPages();
163-
this._emitPageEvent();
177+
this._emitPageEvent(previousPageIndex);
164178
}
165179

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

211+
this.pageIndex = Math.floor(startIndex / pageSize) || 0;
197212
this.pageSize = pageSize;
198-
this._emitPageEvent();
213+
this._emitPageEvent(previousPageIndex);
199214
}
200215

201216
/**
@@ -213,19 +228,20 @@ export class MatPaginator implements OnInit, OnDestroy {
213228
}
214229

215230
this._displayedPageSizeOptions = this.pageSizeOptions.slice();
216-
if (this._displayedPageSizeOptions.indexOf(this.pageSize) == -1) {
231+
232+
if (this._displayedPageSizeOptions.indexOf(this.pageSize) === -1) {
217233
this._displayedPageSizeOptions.push(this.pageSize);
218234
}
219235

220236
// Sort the numbers using a number-specific sort function.
221237
this._displayedPageSizeOptions.sort((a, b) => a - b);
222-
223238
this._changeDetectorRef.markForCheck();
224239
}
225240

226241
/** Emits an event notifying that a change of the paginator's properties has been triggered. */
227-
private _emitPageEvent() {
242+
private _emitPageEvent(previousPageIndex: number) {
228243
this.page.emit({
244+
previousPageIndex,
229245
pageIndex: this.pageIndex,
230246
pageSize: this.pageSize,
231247
length: this.length

src/lib/table/table.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ describe('MatTable', () => {
277277
component.sort.sort(component.sortHeader);
278278
fixture.detectChanges();
279279
expectTableToMatchContent(tableElement, [
280-
['Column A\xa0Sorted by a ascending', 'Column B', 'Column C'],
280+
['Column A', 'Column B', 'Column C'],
281281
['-1', 'b_3', 'c_3'],
282282
['0', 'b_2', 'c_2'],
283283
['1', 'b_1', 'c_1'],
@@ -289,7 +289,7 @@ describe('MatTable', () => {
289289
component.sort.sort(component.sortHeader);
290290
fixture.detectChanges();
291291
expectTableToMatchContent(tableElement, [
292-
['Column A\xa0Sorted by a descending', 'Column B', 'Column C'],
292+
['Column A', 'Column B', 'Column C'],
293293
['1', 'b_1', 'c_1'],
294294
['0', 'b_2', 'c_2'],
295295
['-1', 'b_3', 'c_3'],

0 commit comments

Comments
 (0)