请求数量有限的服务器端分页



我的前端是Angular5。后端是 REST API NODE.JS数据库是 POSTGRES。

我的帖子中名为组织的表包含 100k (100 000( 行。

我有表格,其中包含所有组织的列表以及组织名称,位置等信息。

目前,我的前端仅显示 50 个组织。 我已经控制台记录了这个,我的后端只发送 50 个数组。

我的目标是使用服务器端分页在前端表中显示所有组织(其中 100 000 个(。

已经对显示的当前值进行了分页,即其中的 50 个。代码如下

下面的前端表有效(目前仅显示从后端发送的 50 个组织(

<div class="card-body">
<div class="row">
<div class="table-col">
<div class="card table">
<div class="row header">
<div class="col col-md-6">Name</div>
<div class="col col-md-2">ID</div>
<div class="col col-md-2">Location</div>
<div class="col col-md-2">Person in charge</div>
</div>
<div *ngFor="let group of organizations">
<div *ngIf="group.name == 'all'">
<div class="row content-row" *ngFor="let organization of group.array |  search: term | orderBy: order | paginate: {itemsPerPage: 13, currentPage:page1, id: '1'}"
[routerLink]="['/organization/edit', organization.id]">
<div class="col col-md-6">{{organization.name}}</div>
<div class="col col-md-2">{{organization.id}}</div>
<div class="col col-md-2"  *ngIf="organization.place?.fullName != null">{{organization.place?.fullName}}</div>
<div class="col col-md-2"  *ngIf="organization.place?.fullName == null"><span class="badge badge-danger">-- N/A -- </span></div>
<div *ngIf="organization.person?.fullname != null" class="col col-md-2">{{organization.person?.fullname}}
</div>
<div *ngIf="organization.person?.fullname == null" class="col col-md-2"><span class="badge badge-danger">-- N/A -- </span></div> 

</div>
</div>
<div *ngIf="group.name != 'all'">
<div class="row content-row">
<div class="col col-md-12 group-name" (click)="toggleGroup(group.name)">{{group.name + ':'}}</div>
</div>
<div *ngIf="showGroup == group.name">
<div class="row content-row" *ngFor="let organization of group.array | search: term |   paginate: {itemsPerPage: 5, currentPage:page2, id: '2'}"
[routerLink]="['/organization/edit', organization.id]">
<div class="col col-md-6" style="padding-left:23px;">{{organization.name}}</div>
<div class="col col-md-2">{{organization.id}}</div>
<div class="col col-md-2">{{organization.place?.fullName}}</div>
<div class="col col-md-2">{{organization.person?.fullname}}
</div>
</div>
</div>
</div>
</div>
<div *ngIf="!(organizations[0].array.length > 0)" class="row noResults">
<label>No results..</label>
</div>
<div *ngIf="organizations[0].name == 'all'" class="paggination-row">
<div class="paggination">
<pagination-controls (pageChange)="page1 = $event" id="1" maxSize="5" directionLinks="true" autoHide="true" previousLabel="Previous"
nextLabel="Next">
</pagination-controls>
</div>
</div>
<div *ngIf="organizations[0].name != 'all' && showGroup != ''" class="paggination-row">
<div class="paggination">
<pagination-controls (pageChange)="page2 = $event" id="2" maxSize="5" directionLinks="true" autoHide="true" previousLabel="Previous"
nextLabel="Next">
</pagination-controls>
</div>
</div>
</div>
</div>
</div>
</div>

现在在我的配置的后端,我有以下代码:

"host": "0.0.0.0",
"port": 3030,
"public": "../public/",
"paginate": {
"default": 50,
"max": 50
},

注意:主机 ip 是故意更改的。 分页是我的前线在有 100 000 个值时只收到 100 个值的原因。

现在,如果我继续将默认值和最大值更改为 100k,我的前端应该显示所有组织,但可能会在执行此操作的过程中使客户端和服务器崩溃。

如果我确实分页错误,那也不会有太大帮助。

现在我想知道我如何保持有限的请求,如 50 或 100(所以我的服务器是活的(,但仍然使用服务器端分页或任何必要的方式显示我的前端中的所有组织。

任何帮助都值得赞赏,非常感谢您抽出宝贵时间阅读本文。

编辑1:加载所有组织的服务:

import { Injectable } from '@angular/core';
import { Http, Headers } from "@angular/http";
import 'rxjs/add/operator/map';
import { AppSettings } from '../../../../../../app.settings';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
//service made to comunicate with backend
@Injectable()
export class CreateOrganizacijeService {
private dataSource = new BehaviorSubject<any>("default")
currentData = this.dataSource.asObservable();
constructor(
private http: Http
) { }
updateData(data) {
this.dataSource.next(data);
}
getAll() {
let headers = new Headers();
let token = localStorage.getItem('feathers-jwt');
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Bearer ' + token)
return this.http.get(AppSettings.API_ENDPOINT + '/organization', { headers: headers }).map(res => res.json())
}
getOne(id) {
let headers = new Headers();
let token = localStorage.getItem('feathers-jwt');
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Bearer ' + token)
return this.http.get(AppSettings.API_ENDPOINT + '/organization?id=' + id, { headers: headers }).map(res => res.json())
}
createNew(organization) {
let headers = new Headers();
let token = localStorage.getItem('feathers-jwt');
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Bearer ' + token)
return this.http.post(AppSettings.API_ENDPOINT + '/organization', organization, { headers: headers }).map(res => res.json())
}
delete(id) {
let headers = new Headers();
let token = localStorage.getItem('feathers-jwt');
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Bearer ' + token)
return this.http.delete(AppSettings.API_ENDPOINT + '/organization?id=' + id, { headers: headers }).map(res => res.json())
}
edit(id, organization) {
let headers = new Headers();
let token = localStorage.getItem('feathers-jwt');
headers.append('Content-Type', 'application/json');
headers.append('Authorization', 'Bearer ' + token)
return this.http.patch(AppSettings.API_ENDPOINT + '/organization?id=' + id, organization, { headers: headers }).map(res => res.json())
}
}

组件 ngonit(我加载组织的地方(

ngOnInit() {
this.currentUser = JSON.parse(localStorage.getItem('user'));
if(this.currentUser.roleId == '2') {
this.isAdmin = true; //check if user is admin
}
if(JSON.parse(localStorage.getItem('user')).roleId == '2') {
this.isAdmin = true; //check if user is admin
}
this.organizacijeService.currentData.subscribe(res => {
this.loadOrgs();
})

}
loadOrgs() {
this.organizacijeService.getAll().subscribe(res => {
this.organizations[0].array = res.data;
console.log(this.organizations[0])
}, err => {
this.toast.error('Organization: ' + JSON.parse(err._body).message, 'Failed')
})
}

您可以通过以50 为增量增加 $skip 查询参数来加载后续页面,直到page.total - 50

请记住,一次显示 100k 条记录可能仍会导致前端的性能问题。

您可以在服务器端使用禁用分页的代理服务:

app.use('organizations-unpaginated', {
find(params){
const _params = Object.assign({}, params, { paginate: false });
return app.service('organizations').find(_params);
}
})

正如 Daff 所说,你会遇到性能问题,我通常会说渲染 100k DOM 元素(几乎所有元素都是不可见的(是一种不好的做法。

最新更新