ngx-pagination:Angular 6 服务器端实现
Posted
技术标签:
【中文标题】ngx-pagination:Angular 6 服务器端实现【英文标题】:ngx-pagination: Angular 6 server side implementation 【发布时间】:2019-03-22 10:54:00 【问题描述】:我正在尝试使用 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 返回数据。
为了安全起见,我将方法更改为async
,现在看起来像这样:
async getsample()
try
await this.api.get('sample').subscribe((data) =>
this.sample = data.body.data;
this.meta = data.body.meta;
);
catch (error)
我也实现了布兰登给出的答案,但问题仍然存在。
【问题讨论】:
我认为问题在于this.getsample()
订阅尚未执行(因此 sample
和 meta
未设置)并且您正在尝试读取这些属性(在 serverCall(...)
中)。这是async
问题。
谢谢@miselking,我感觉可能是问题所在。我在下面尝试了布兰登的建议,但没有奏效。您还有其他解决方案吗?
【参考方案1】:
您的代码还有更多问题,其中之一是您对 this.getsample();
的异步调用,但您无需等待结果。
另一件事是你不能等待 observable。首先通过.toPromise()
将其转换为promise,而不是订阅,或者根本不使用promise 而是订阅(但仅在最顶层 - 在ngOnInit
处理程序中)。
使用异步/等待:
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;
【讨论】:
这让我更接近修复,谢谢。问题是我不能在 Promise 上使用 AsyncPipe,但也许我不会。pagedItems
的 items 数组仍然返回空。
你绝对可以在 promise 上使用异步管道
好的,因为我对这个很陌生,所以我需要引导我完成这个。我已经实现了您的答案,但打字稿抱怨我无法将类型 any
分配给 Observable。 @马丁
您的代码中可能仍有一些错误的类型提示(我在 main 中没有使用Observable
类型提示,因此错误不是由它引起的)。顺便说一句,我想我发现了你的问题。在getPage
方法中使用它之后,您正在调用getsample()
- 您需要先加载它。
然后将 getsample 调用移动到 getPage 方法的第一行【参考方案2】:
这是一个异步/等待问题。
ngOnInit()
this.getPage(1);
应该是:
async ngOnInit()
await this.getPage(1);
否则,this.pagedItems
将在 serverCall()
完成之前为空。
【讨论】:
感谢@Brandon 的帮助,但不幸的是,这并没有解决问题。以上是关于ngx-pagination:Angular 6 服务器端实现的主要内容,如果未能解决你的问题,请参考以下文章
Angular,TypeError:无法读取未定义的属性“排序”