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.
This commit is contained in:
Kristiyan Kostadinov
2018-04-25 12:58:45 -04:00
committed by Andrew Seguin
parent 848fe58980
commit 85039ca8e0
2 changed files with 67 additions and 38 deletions
+42 -29
View File
@@ -1,6 +1,6 @@
import {async, ComponentFixture, TestBed, inject, tick, fakeAsync} from '@angular/core/testing';
import {MatPaginatorModule} from './index';
import {MatPaginator, PageEvent} from './paginator';
import {MatPaginator} from './paginator';
import {Component, ViewChild} from '@angular/core';
import {MatPaginatorIntl} from './paginator-intl';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
@@ -111,7 +111,10 @@ describe('MatPaginator', () => {
dispatchMouseEvent(getNextButton(fixture), 'click');
expect(paginator.pageIndex).toBe(1);
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(1);
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
previousPageIndex: 0,
pageIndex: 1
}));
});
it('should be able to go to the previous page', () => {
@@ -122,7 +125,10 @@ describe('MatPaginator', () => {
dispatchMouseEvent(getPreviousButton(fixture), 'click');
expect(paginator.pageIndex).toBe(0);
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(0);
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
previousPageIndex: 1,
pageIndex: 0
}));
});
});
@@ -169,7 +175,10 @@ describe('MatPaginator', () => {
dispatchMouseEvent(getLastButton(fixture), 'click');
expect(paginator.pageIndex).toBe(9);
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(9);
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
previousPageIndex: 0,
pageIndex: 9
}));
});
it('should be able to go to the first page via the first page button', () => {
@@ -180,7 +189,10 @@ describe('MatPaginator', () => {
dispatchMouseEvent(getFirstButton(fixture), 'click');
expect(paginator.pageIndex).toBe(0);
expect(component.latestPageEvent ? component.latestPageEvent.pageIndex : null).toBe(0);
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
previousPageIndex: 3,
pageIndex: 0
}));
});
it('should disable navigating to the next page if at last page', () => {
@@ -189,10 +201,10 @@ describe('MatPaginator', () => {
expect(paginator.pageIndex).toBe(9);
expect(paginator.hasNextPage()).toBe(false);
component.latestPageEvent = null;
component.pageEvent.calls.reset();
dispatchMouseEvent(getNextButton(fixture), 'click');
expect(component.latestPageEvent).toBe(null);
expect(component.pageEvent).not.toHaveBeenCalled();
expect(paginator.pageIndex).toBe(9);
});
@@ -200,10 +212,10 @@ describe('MatPaginator', () => {
expect(paginator.pageIndex).toBe(0);
expect(paginator.hasPreviousPage()).toBe(false);
component.latestPageEvent = null;
component.pageEvent.calls.reset();
dispatchMouseEvent(getPreviousButton(fixture), 'click');
expect(component.latestPageEvent).toBe(null);
expect(component.pageEvent).not.toHaveBeenCalled();
expect(paginator.pageIndex).toBe(0);
});
@@ -270,35 +282,37 @@ describe('MatPaginator', () => {
fixture.detectChanges();
// The first item of the page should be item with index 40
let firstPageItemIndex: number | null = paginator.pageIndex * paginator.pageSize;
expect(firstPageItemIndex).toBe(40);
expect(paginator.pageIndex * paginator.pageSize).toBe(40);
// The first item on the page is now 25. Change the page size to 25 so that we should now be
// on the second page where the top item is index 25.
component.pageEvent.calls.reset();
paginator._changePageSize(25);
let paginationEvent = component.latestPageEvent;
firstPageItemIndex = paginationEvent ?
paginationEvent.pageIndex * paginationEvent.pageSize : null;
expect(firstPageItemIndex).toBe(25);
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(1);
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
pageIndex: 1,
pageSize: 25
}));
// The first item on the page is still 25. Change the page size to 8 so that we should now be
// on the fourth page where the top item is index 24.
component.pageEvent.calls.reset();
paginator._changePageSize(8);
paginationEvent = component.latestPageEvent;
firstPageItemIndex = paginationEvent ?
paginationEvent.pageIndex * paginationEvent.pageSize : null;
expect(firstPageItemIndex).toBe(24);
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(3);
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
pageIndex: 3,
pageSize: 8
}));
// The first item on the page is 24. Change the page size to 16 so that we should now be
// on the first page where the top item is index 0.
component.pageEvent.calls.reset();
paginator._changePageSize(25);
paginationEvent = component.latestPageEvent;
firstPageItemIndex = paginationEvent ?
paginationEvent.pageIndex * paginationEvent.pageSize : null;
expect(firstPageItemIndex).toBe(0);
expect(paginationEvent ? paginationEvent.pageIndex : null).toBe(0);
expect(component.pageEvent).toHaveBeenCalledWith(jasmine.objectContaining({
pageIndex: 0,
pageSize: 25
}));
});
it('should show a select only if there are multiple options', () => {
@@ -363,7 +377,7 @@ function getLastButton(fixture: ComponentFixture<any>) {
[hidePageSize]="hidePageSize"
[showFirstLastButtons]="showFirstLastButtons"
[length]="length"
(page)="latestPageEvent = $event">
(page)="pageEvent($event)">
</mat-paginator>
`,
})
@@ -374,8 +388,7 @@ class MatPaginatorApp {
hidePageSize = false;
showFirstLastButtons = false;
length = 100;
latestPageEvent: PageEvent | null;
pageEvent = jasmine.createSpy('page event');
@ViewChild(MatPaginator) paginator: MatPaginator;
+25 -9
View File
@@ -33,6 +33,12 @@ export class PageEvent {
/** The current page index. */
pageIndex: number;
/**
* Index of the page that was selected previously.
* @deletion-target 7.0.0 To be made into a required property.
*/
previousPageIndex?: number;
/** The current page size */
pageSize: number;
@@ -144,31 +150,39 @@ export class MatPaginator extends _MatPaginatorBase implements OnInit, OnDestroy
/** Advances to the next page if it exists. */
nextPage(): void {
if (!this.hasNextPage()) { return; }
const previousPageIndex = this.pageIndex;
this.pageIndex++;
this._emitPageEvent();
this._emitPageEvent(previousPageIndex);
}
/** Move back to the previous page if it exists. */
previousPage(): void {
if (!this.hasPreviousPage()) { return; }
const previousPageIndex = this.pageIndex;
this.pageIndex--;
this._emitPageEvent();
this._emitPageEvent(previousPageIndex);
}
/** Move to the first page if not already there. */
firstPage(): void {
// hasPreviousPage being false implies at the start
if (!this.hasPreviousPage()) { return; }
const previousPageIndex = this.pageIndex;
this.pageIndex = 0;
this._emitPageEvent();
this._emitPageEvent(previousPageIndex);
}
/** Move to the last page if not already there. */
lastPage(): void {
// hasNextPage being false implies at the end
if (!this.hasNextPage()) { return; }
const previousPageIndex = this.pageIndex;
this.pageIndex = this.getNumberOfPages();
this._emitPageEvent();
this._emitPageEvent(previousPageIndex);
}
/** Whether there is a previous page. */
@@ -200,10 +214,11 @@ export class MatPaginator extends _MatPaginatorBase implements OnInit, OnDestroy
// Current page needs to be updated to reflect the new page size. Navigate to the page
// containing the previous page's first item.
const startIndex = this.pageIndex * this.pageSize;
this.pageIndex = Math.floor(startIndex / pageSize) || 0;
const previousPageIndex = this.pageIndex;
this.pageIndex = Math.floor(startIndex / pageSize) || 0;
this.pageSize = pageSize;
this._emitPageEvent();
this._emitPageEvent(previousPageIndex);
}
/**
@@ -221,19 +236,20 @@ export class MatPaginator extends _MatPaginatorBase implements OnInit, OnDestroy
}
this._displayedPageSizeOptions = this.pageSizeOptions.slice();
if (this._displayedPageSizeOptions.indexOf(this.pageSize) == -1) {
if (this._displayedPageSizeOptions.indexOf(this.pageSize) === -1) {
this._displayedPageSizeOptions.push(this.pageSize);
}
// Sort the numbers using a number-specific sort function.
this._displayedPageSizeOptions.sort((a, b) => a - b);
this._changeDetectorRef.markForCheck();
}
/** Emits an event notifying that a change of the paginator's properties has been triggered. */
private _emitPageEvent() {
private _emitPageEvent(previousPageIndex: number) {
this.page.emit({
previousPageIndex,
pageIndex: this.pageIndex,
pageSize: this.pageSize,
length: this.length