ngx-pagination: Angular 6 服务器端实现
ngx-pagination: Angular 6 server side implementation
我正在尝试使用 ngx-pagination
在我的 Angular 6 应用程序上实现服务器端分页。
我已尽我所能遵循 documentation,但我遇到了以下问题,不知道如何继续。
问题
组件从 api 加载并获取数据,但直到 之后才显示在渲染器上 我会再调用两次api 导航到下一页,然后导航到上一页。
api 第二页的数据未被调用。
截图
初始页面加载
来回导航后
示例代码
import { Component, OnInit, Input, ChangeDetectionStrategy } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ApiService } from '../../services/api.service';
import { SiteUrls } from '../../services/constants.service';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import 'rxjs/add/operator/delay';
interface IServerResponse {
items: any[];
total: number;
}
@Component({
selector: 'app-sample',
templateUrl: './sample.component.html',
styleUrls: ['./sample.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SampleComponent implements OnInit {
@Input() sample: any = [{}];
total: number;
p = 1;
pagedItems: Observable<any[]>;
public meta: any = {};
constructor(private site: SiteUrls, private http: Http, private api: ApiService) {}
ngOnInit() {
this.getPage(1);
}
async getPage(page: number) {
this.pagedItems = this.serverCall(this.sample, page)
.pipe(tap((res) => {
this.total = res.total;
this.p = page;
console.log('total', this.total, 'page', this.p, 'res', res);
})).pipe(map((res) => res.items));
}
serverCall(sample: any[], page: number): Observable<IServerResponse> {
this.getsample();
const perPage = this.meta.per_page;
const start = (page - 1) * perPage;
const end = start + perPage;
return of({
items: sample.slice(start, end),
total: this.meta.total
}).delay(1000);
}
private getsample() {
this.api.get('sample').subscribe((data) => {
this.sample = data.body.data;
this.meta = data.body.meta;
});
}
}
<tbody>
<tr *ngFor="let tran of pagedItems | async | paginate: { itemsPerPage: meta.per_page, currentPage: p, totalItems: meta.total }">
<td>
{{tran.account.number}}
</td>
<td>
{{tran.sender.name}}
</td>
<td>
{{tran.recipient.name}}
</td>
<td>
{{tran.date | date: 'MMMM dd, yyyy'}}
</td>
<td style="background-color: antiquewhite">
{{tran.subtotal | currency}}
</td>
<td style="background-color: antiquewhite">
{{tran.fee | currency}}
</td>
<td style="background-color: antiquewhite">
<b>{{tran.total | currency}}</b>
</td>
</tr>
</tbody>
</table>
<pagination-controls (pageChange)="getPage($event)"></pagination-controls>
如有任何帮助,我们将不胜感激。
更新
getsample()
正在页面加载和 api returns 数据上执行。
为了安全起见,我将方法更改为 async
,现在看起来像这样:
async getsample() {
try {
await this.api.get('sample').subscribe((data) => {
this.sample = data.body.data;
this.meta = data.body.meta;
});
} catch (error) {}
}
我也执行了布兰登给出的答案,但问题仍然存在。
这是一个 async/await 问题。
ngOnInit() {
this.getPage(1);
}
应该是:
async ngOnInit() {
await this.getPage(1);
}
否则,this.pagedItems
将为空,直到 serverCall()
完成。
您的代码还有更多问题,其中之一是您对 this.getsample();
的调用是异步的,但您没有等待结果。
另一件事是你不能等待观察。首先通过 .toPromise()
而不是订阅将其转换为承诺,或者根本不使用承诺并改为订阅(但仅在最顶层 - 在 ngOnInit
处理程序中)。
使用async/await:
async ngOnInit() {
await this.getsample(); // move the loading here
await this.getPage(1);
}
async getPage(page: number) {
const res = await this.serverCall(this.sample, page);
this.total = res.total;
this.p = page;
console.log('total', this.total, 'page', this.p, 'res', res);
this.pagedItems = res.items;
}
async serverCall(sample: any[], page: number): Promise<IServerResponse> {
const perPage = this.meta.per_page;
const start = (page - 1) * perPage;
const end = start + perPage;
return of({
items: sample.slice(start, end),
total: this.meta.total
}).delay(1000).toPromise(); // convert the observable to promise
}
private async getsample() {
const data = await this.api.get('sample').toPromise(); // and again here
this.sample = data.body.data;
this.meta = data.body.meta;
}
我正在尝试使用 ngx-pagination
在我的 Angular 6 应用程序上实现服务器端分页。
我已尽我所能遵循 documentation,但我遇到了以下问题,不知道如何继续。
问题
组件从 api 加载并获取数据,但直到 之后才显示在渲染器上 我会再调用两次api 导航到下一页,然后导航到上一页。
api 第二页的数据未被调用。
截图
初始页面加载
来回导航后
示例代码
import { Component, OnInit, Input, ChangeDetectionStrategy } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ApiService } from '../../services/api.service';
import { SiteUrls } from '../../services/constants.service';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import 'rxjs/add/operator/delay';
interface IServerResponse {
items: any[];
total: number;
}
@Component({
selector: 'app-sample',
templateUrl: './sample.component.html',
styleUrls: ['./sample.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SampleComponent implements OnInit {
@Input() sample: any = [{}];
total: number;
p = 1;
pagedItems: Observable<any[]>;
public meta: any = {};
constructor(private site: SiteUrls, private http: Http, private api: ApiService) {}
ngOnInit() {
this.getPage(1);
}
async getPage(page: number) {
this.pagedItems = this.serverCall(this.sample, page)
.pipe(tap((res) => {
this.total = res.total;
this.p = page;
console.log('total', this.total, 'page', this.p, 'res', res);
})).pipe(map((res) => res.items));
}
serverCall(sample: any[], page: number): Observable<IServerResponse> {
this.getsample();
const perPage = this.meta.per_page;
const start = (page - 1) * perPage;
const end = start + perPage;
return of({
items: sample.slice(start, end),
total: this.meta.total
}).delay(1000);
}
private getsample() {
this.api.get('sample').subscribe((data) => {
this.sample = data.body.data;
this.meta = data.body.meta;
});
}
}
<tbody>
<tr *ngFor="let tran of pagedItems | async | paginate: { itemsPerPage: meta.per_page, currentPage: p, totalItems: meta.total }">
<td>
{{tran.account.number}}
</td>
<td>
{{tran.sender.name}}
</td>
<td>
{{tran.recipient.name}}
</td>
<td>
{{tran.date | date: 'MMMM dd, yyyy'}}
</td>
<td style="background-color: antiquewhite">
{{tran.subtotal | currency}}
</td>
<td style="background-color: antiquewhite">
{{tran.fee | currency}}
</td>
<td style="background-color: antiquewhite">
<b>{{tran.total | currency}}</b>
</td>
</tr>
</tbody>
</table>
<pagination-controls (pageChange)="getPage($event)"></pagination-controls>
如有任何帮助,我们将不胜感激。
更新
getsample()
正在页面加载和 api returns 数据上执行。
为了安全起见,我将方法更改为 async
,现在看起来像这样:
async getsample() {
try {
await this.api.get('sample').subscribe((data) => {
this.sample = data.body.data;
this.meta = data.body.meta;
});
} catch (error) {}
}
我也执行了布兰登给出的答案,但问题仍然存在。
这是一个 async/await 问题。
ngOnInit() {
this.getPage(1);
}
应该是:
async ngOnInit() {
await this.getPage(1);
}
否则,this.pagedItems
将为空,直到 serverCall()
完成。
您的代码还有更多问题,其中之一是您对 this.getsample();
的调用是异步的,但您没有等待结果。
另一件事是你不能等待观察。首先通过 .toPromise()
而不是订阅将其转换为承诺,或者根本不使用承诺并改为订阅(但仅在最顶层 - 在 ngOnInit
处理程序中)。
使用async/await:
async ngOnInit() {
await this.getsample(); // move the loading here
await this.getPage(1);
}
async getPage(page: number) {
const res = await this.serverCall(this.sample, page);
this.total = res.total;
this.p = page;
console.log('total', this.total, 'page', this.p, 'res', res);
this.pagedItems = res.items;
}
async serverCall(sample: any[], page: number): Promise<IServerResponse> {
const perPage = this.meta.per_page;
const start = (page - 1) * perPage;
const end = start + perPage;
return of({
items: sample.slice(start, end),
total: this.meta.total
}).delay(1000).toPromise(); // convert the observable to promise
}
private async getsample() {
const data = await this.api.get('sample').toPromise(); // and again here
this.sample = data.body.data;
this.meta = data.body.meta;
}