Вступление
В этой статье мы узнаем, как мы создаем нумерацию на стороне сервера, что очень полезно, когда нам нужно отобразить большое количество записей. Это вторая часть моей статьи о разбиении на страницы на сервере, вы можете ознакомиться с первой частью этой статьи по ссылке ниже.
Вам также могут понравиться:
разбиение на страницы на стороне сервера с использованием ASP.NET Core и Angular 8
Как это будет работать?
В этой статье мы собираемся показать предыдущую и следующую кнопки с пользовательской логикой, поэтому всякий раз, когда мы нажимаем на следующую кнопку, она показывает следующую страницу записей. Например, предположим, что мы на первой странице и после нажатия на кнопку «Далее» будет показана вторая страница записей. Однако здесь мы увидим другую логику.
Backend
Здесь, в предыдущей статье, мы уже создали базу данных и таблицы, поэтому нет необходимости создавать ее снова. Если у вас нет связанной базы данных, таблиц и хранимых процедур, пожалуйста, проверьте предыдущую статью .
Веб-API
Полный код пагинации контроллера:
C #
1
using System.Collections.Generic;
2
using System.Data.Entity.Core.Objects;
3
using System.Linq;
4
using System.Web.Http;
5
using Pagination.Models;
6
namespace Pagination.Controllers
7
{
8
public class PaginationController : ApiController
9
{
10
CompanyEntities2 db = new CompanyEntities2();
11
12
[HttpGet]
13
public object getAllCompanies(int pageNo, int pageSize, string sortOrder)
14
{
15
16
var oMyString = new ObjectParameter("totalCount", typeof(int));
17
18
var companyDetails = db.Usp_GetAllCompanies(pageNo, pageSize, sortOrder).ToList();
19
return companyDetails;
20
}
21
22
[HttpGet]
23
public object getAllCompaniesCount()
24
{
25
26
var companyDetailsCount = db.Usp_getAllCompaniesCount().SingleOrDefault();
27
return companyDetailsCount;
28
}
29
}
30
}
Внешний интерфейс
Шаг 1
Давайте скопируем HTML-код и заменим его файлом pagination.html. Я внес некоторые изменения по сравнению с первой частью, добавив новые кнопки для проверки количества записей на одной странице, поэтому при нажатии на 10 на одной странице будет отображаться 10 записей.
HTML
xxxxxxxxxx
1
<div class="row">
2
<div class="col-12 col-md-12">
3
<div class="card">
4
<div class="card-header">
5
<div class="row">
6
<div>
7
Companies 1-{{pageSize}} (Total:{{totalCompaniesCount}})
8
</div>
9
<div style="margin: auto;" class="add-row add-row-rel top-paging">
10
<span class="cpp">Companies per page:</span>
11
<a (click)="setRecPerPage(small)" [ngClass]="smallPageRow? 'active':'mr-2'">{{small}}</a>
12
<a (click)="setRecPerPage(medium)" [ngClass]="mediumPageRow? 'active':'mr-2'">{{medium}}</a>
13
<a (click)="setRecPerPage(large)" [ngClass]="largePageRow? 'active':'mr-2'">{{large}}</a>
14
</div>
15
</div>
16
</div>
17
<div class="card-body position-relative">
18
<!-- <div class="tbl-note-dentist">
19
Sort list by select <span>table headers</span>, click again to reorder
20
ascending/descending
21
</div> -->
22
<div class="table-responsive cnstr-record companie-tbl">
23
<table class="table table-bordered heading-hvr">
24
<thead>
25
<tr>
26
<th style="cursor: pointer;" [ngClass]="order =='CompanyNumber'? 'active':''"
27
(click)="setOrder('CompanyNumber')" width="80">Company Name.</th>
28
<th style="cursor: pointer;" [ngClass]="order =='CompanyType'? 'active':''"
29
(click)="setOrder('CompanyType')" width="75">City</th>
30
<th [ngClass]="order =='CompanyName'? 'active':''" style="cursor: pointer;"
31
(click)="setOrder('CompanyName')">State
32
</th>
33
<th [ngClass]="order =='OrgNo'? 'active':''" style="cursor: pointer;" (click)="setOrder('OrgNo')"
34
width="75">CEO
35
</th>
36
<th [ngClass]="order =='Street'? 'active':''" style="cursor: pointer; width:250px"
37
(click)="setOrder('Street')">Publish Year</th>
38
</tr>
39
</thead>
40
<tbody>
41
<tr *ngFor="let item of companies">
42
<td>{{item.CompanyName}}</td>
43
<td>{{item.City}}</td>
44
<td>{{item.State}}</td>
45
<td>{{item.Owner}}</td>
46
<td>{{item.PublishYear}}</td>
47
</tr>
48
</tbody>
49
</table>
50
</div>
51
<!-- Code by pagination -->
52
<div class="container mw-100">
53
<div class="row">
54
<div class="col-md-3"></div>
55
<div *ngIf="companies !=0" class="col-md-6">
56
<ul class="pagination justify-content-center">
57
<li class="page-item">
58
<a (click)="showPrevCompanies()"
59
[ngClass]="(paginationService.showNoOfCurrentPage ==1)?'notAllowed':'page-link'"
60
style="margin-top: 5px; margin-right: 20px;cursor: pointer;">Prev</a>
61
</li>
62
<li *ngFor="let page of pageField;let i=index" class="page-item">
63
<a (click)="showCompaniesByPageNumber(page,i)" [ngClass]="pageNumber[i] ? 'pageColor':'page-link'"
64
style=" margin-right: 5px;;margin-top: 5px;cursor: pointer;">{{page}}</a>
65
</li>
66
<li class="page-item">
67
<a (click)="showNextCompanies()"
68
[ngClass]="(paginationService.disabledNextBtn)?'notAllowed':'page-link'"
69
style="margin-top: 5px;margin-left: 20px; cursor: pointer;">Next</a>
70
</li>
71
</ul>
72
<div style="text-align: center;">
73
Page {{currentPage}} of Total page {{paginationService.exactPageList}}
74
</div>
75
</div>
76
</div>
77
</div>
78
</div>
79
</div>
80
</div>
81
</div>
Шаг 2
В CSS-файле есть некоторые изменения, поэтому просто замените этот код на файл pagination.component.css.
CSS
xxxxxxxxxx
1
@charset "utf-8";
2
/* CSS Document */
3
@media all {
4
*{
5
padding: 0 px;margin: 0 px;
6
}
7
div {
8
vertical - align: top;
9
}
10
img {
11
max - width: 100 % ;
12
}
13
html {
14
-webkit - font - smoothing: antialiased; - moz - osx - font - smoothing: grayscale;
15
}
16
body {
17
overflow: auto!important;width: 100 % !important;
18
}
19
html, body {
20
background - color: #e4e5e6;
21
}
22
html {
23
position: relative;min - height: 100 % ;
24
}.card {
25
border - radius: 4 px;
26
}.card - header: first - child {
27
border - radius: 4 px 4 px 0 px 0 px;
28
}
29
/*Typekit*/
30
html, body {
31
font - family: 'Roboto', sans - serif;
32
font - weight: 400;
33
font - size: 13 px;
34
}
35
body {
36
padding - top: 52 px;
37
}
38
p {
39
font - family: 'Roboto', sans - serif;
40
color: #303030; font-weight:400; margin-bottom:1rem;}
41
input, textarea, select{font-family:'Roboto', sans-serif;}
42
h1,h2,h3,h4,h5,h6{font-family:'Roboto', sans-serif; font-weight:700;}
43
h1{font-size:20px; color:# 000000;
44
margin - bottom: 10 px;
45
}
46
h2 {
47
font - size: 30 px;
48
}
49
h3 {
50
font - size: 24 px;
51
}
52
h4 {
53
font - size: 18 px;
54
}
55
h5 {
56
font - size: 14 px;
57
}
58
h6 {
59
font - size: 12 px;
60
}.row {
61
margin - right: -8 px;
62
margin - left: -8 px;
63
}.col, .col - 1, .col - 10, .col - 11, .col - 12, .col - 2, .col - 3, .col - 4, .col - 5, .col - 6, .col - 7, .col - 8, .col - 9, .col - auto, .col - lg, .col - lg - 1, .col - lg - 10, .col - lg - 11, .col - lg - 12, .col - lg - 2, .col - lg - 3, .col - lg - 4, .col - lg - 5, .col - lg - 6, .col - lg - 7, .col - lg - 8, .col - lg - 9, .col - lg - auto, .col - md, .col - md - 1, .col - md - 10, .col - md - 11, .col - md - 12, .col - md - 2, .col - md - 3, .col - md - 4, .col - md - 5, .col - md - 6, .col - md - 7, .col - md - 8, .col - md - 9, .col - md - auto, .col - sm, .col - sm - 1, .col - sm - 10, .col - sm - 11, .col - sm - 12, .col - sm - 2, .col - sm - 3, .col - sm - 4, .col - sm - 5, .col - sm - 6, .col - sm - 7, .col - sm - 8, .col - sm - 9, .col - sm - auto, .col - xl, .col - xl - 1, .col - xl - 10, .col - xl - 11, .col - xl - 12, .col - xl - 2, .col - xl - 3, .col - xl - 4, .col - xl - 5, .col - xl - 6, .col - xl - 7, .col - xl - 8, .col - xl - 9, .col - xl - auto {
64
padding - right: 8 px;
65
padding - left: 8 px;
66
}.card - header {
67
background - color: #f0f3f5;
68
border - bottom: 1 px solid #c8ced3;
69
font - size: 13 px;
70
font - weight: 600;
71
color: #464646; text-transform:uppercase; padding:.75rem 8px;}
72
.cnstr-record th{white-space:nowrap;padding:.45rem .2rem; font-size:13px; border-bottom-width:0px!important;}
73
.cnstr-record thead{background:# f0f3f5;
74
}.cnstr - record.form - control {
75
font - size: 13 px;
76
padding: 0 px 0 rem 0 px 0.2 rem;
77
height: calc(2 rem + 2 px);
78
}.cnstr - record select.form - control {
79
padding - left: .05 rem;
80
}.cnstr - record.table td, .cnstr - record.table th {
81
vertical - align: middle;
82
}.cnstr - record.table td {
83
padding: .3 rem;
84
}.cnstr - record.table td h4 {
85
margin: 0 px;
86
}.wp - 50 {
87
width: 50 px;
88
}.wp - 60 {
89
width: 60 px;
90
}.wp - 70 {
91
width: 70 px;
92
}.wp - 80 {
93
width: 80 px;
94
}.wp - 90 {
95
width: 90 px;
96
}.wp - 100 {
97
width: 100 px;
98
}.mw - auto {
99
min - width: inherit;
100
}.expand - row {
101
width: 100 % ;border: solid 1 px #596269; display:inline-block; border-radius:3px; width:16px; height:16px; vertical-align:top; background:# 596269;color: #ffffff!important;
102
}.expand - row img {
103
vertical - align: top;
104
position: relative;
105
top: 2 px;
106
}.sub - table th {
107
font - weight: 400;
108
font - size: 12 px;
109
}.sub - table td {
110
background: #efefef;
111
}.no - bg td {
112
background: inherit;
113
}.mw - 100 {
114
max - width: 100 % ;
115
}.activeTabColor {
116
color: #fff;
117
background - color: #000000;
118
}
119
.page-item:first-child .page-link {
120
margin-left: 0;
121
border-top-left-radius: .25rem;
122
border-bottom-left-radius: .25rem;
123
}
124
125
.pageColor{
126
position: relative;
127
display: block;
128
padding: .5rem .75rem;
129
margin-left: -1px;
130
line-height: 1.25;
131
color: white!important;
132
background-color: black!important;
133
border: 1px solid # dee2e6;
134
}.notAllowed {
135
position: relative;
136
display: block;
137
padding: .5 rem .75 rem;
138
margin - left: -1 px;
139
line - height: 1.25;
140
color: #007bff;
141
background-color: # fff;
142
border: 1 px solid #dee2e6;
143
cursor: not - allowed;
144
}.page - link {
145
position: relative;
146
display: block;
147
padding: .5 rem .75 rem;
148
margin - left: -1 px;
149
line - height: 1.25;
150
color: #007bff;
151
background-color: # fff;
152
border: 1 px solid #dee2e6;
153
}.mr - 2 {
154
background - color: #007bff;
155
color: white!important;
156
margin: 5px;
157
padding: 5px;
158
cursor: pointer;
159
}
160
.active{
161
background-color: black;
162
color: white!important;
163
margin: 5px;
164
padding: 5px;
165
cursor: pointer;
166
}
167
168
}
Шаг 3
Скопируйте приведенный ниже код и замените оригинальный файл pagination.component.ts.
JavaScript
xxxxxxxxxx
1
import { Component, OnInit } from '@angular/core';
2
import { ApiService } from './api.service';
3
import { PaginationService } from './pagination.service';
4
import { CompaniesPerPage } from './CompaniesPerPage';
5
6
@Component({
7
selector: 'app-pagination',
8
templateUrl: './pagination.component.html',
9
styleUrls: ['./pagination.component.css']
10
})
11
export class PaginationComponent implements OnInit {
12
13
companies = [];
14
pageNo: any = 1;
15
pageNumber: boolean[] = [];
16
sortOrder: any = 'CompanyName';
17
18
//Pagination Variables
19
//Page Row variables
20
smallPageRow: boolean = true;
21
mediumPageRow: boolean = false;
22
largePageRow: boolean = false;
23
24
small = CompaniesPerPage.small;
25
medium = CompaniesPerPage.medium;
26
large = CompaniesPerPage.large;
27
28
pageField = [];
29
exactPageList: any;
30
paginationData: number;
31
companiesPerPage: any = CompaniesPerPage.small;;
32
totalCompanies: any;
33
totalCompaniesCount: any;
34
currentPage = 1;
35
36
constructor(public service: ApiService, public paginationService: PaginationService) { }
37
38
ngOnInit() {
39
this.pageNumber[0] = true;
40
this.paginationService.temppage = 0;
41
this.getAllCompanies();
42
}
43
getAllCompanies() {
44
this.service.getAllCompanies(this.pageNo, this.companiesPerPage, this.sortOrder).subscribe((data: any) => {
45
this.companies = data;
46
this.getAllCompaniesCount();
47
})
48
}
49
getAllCompaniesCount() {
50
this.service.getAllCompaniesCount().subscribe((res: any) => {
51
this.totalCompaniesCount = res;
52
this.totalNoOfPages();
53
})
54
}
55
56
//Method For Pagination
57
totalNoOfPages() {
58
59
this.paginationData = Number(this.totalCompaniesCount / this.companiesPerPage);
60
let tempPageData = this.paginationData.toFixed();
61
if (Number(tempPageData) < this.paginationData) {
62
this.exactPageList = Number(tempPageData) + 1;
63
this.paginationService.exactPageList = this.exactPageList;
64
} else {
65
this.exactPageList = Number(tempPageData);
66
this.paginationService.exactPageList = this.exactPageList
67
}
68
this.paginationService.pageOnLoad();
69
this.pageField = this.paginationService.pageField;
70
71
}
72
showCompaniesByPageNumber(page, i) {
73
this.companies = [];
74
this.pageNumber = [];
75
this.pageNumber[i] = true;
76
this.pageNo = page;
77
this.currentPage =page;
78
this.getAllCompanies();
79
}
80
81
//Pagination Start
82
83
showPrevCompanies() {
84
85
if (this.paginationService.showNoOfCurrentPage != 1) {
86
this.paginationService.prevCompanies();
87
this.pageNumber = [];
88
this.pageNumber[0] = true;
89
this.currentPage = this.paginationService.pageField[0];
90
this.getAllCompanies();
91
}
92
93
}
94
95
showNextCompanies() {
96
97
if (this.paginationService.disabledNextBtn == false) {
98
this.pageNumber = [];
99
this.paginationService.nextCompanies();
100
this.pageNumber[0] = true;
101
this.currentPage = this.paginationService.pageField[0];
102
this.getAllCompanies();
103
}
104
}
105
106
setRecPerPage(noOfRec) {
107
108
this.companies = [];
109
this.pageNumber = [];
110
this.pageNumber[0] = true;
111
this.paginationService.temppage = 0;
112
if (noOfRec == CompaniesPerPage.small) {
113
this.smallPageRow = true;
114
this.mediumPageRow = false;
115
this.largePageRow = false;
116
this.companiesPerPage = noOfRec;
117
this.currentPage = 1;
118
this.pageNumber[0] = true;
119
this.getAllCompanies();
120
121
}
122
else if (noOfRec == CompaniesPerPage.medium) {
123
this.smallPageRow = false;
124
this.mediumPageRow = true;
125
this.largePageRow = false;
126
this.companiesPerPage = noOfRec;
127
this.currentPage = 1;
128
this.pageNumber[0] = true;
129
this.getAllCompanies();
130
131
} else {
132
this.smallPageRow = false;
133
this.mediumPageRow = false;
134
this.largePageRow = true;
135
this.companiesPerPage = noOfRec;
136
this.currentPage = 1;
137
this.pageNumber[0] = true;
138
this.getAllCompanies();
139
140
}
141
//this.pageSize = page;
142
}
143
}
Шаг 4
Для получения записей на странице мы используем enum
класс CompaniesPerPage.ts
. Создайте новый класс с именем CompaniesPerPage.ts
и вставьте приведенный ниже код.
JavaScript
xxxxxxxxxx
1
export enum CompaniesPerPage {
2
small = 5,
3
medium = 10,
4
large= 15,
5
displayNoOfPagesPerPage=10
6
}
Шаг 5
Для получения записей с сервера необходимо вызвать службу, чтобы связать ее с нашим веб-API, поэтому просто скопируйте приведенный ниже код и вставьте его в файл Api.service.ts.
JavaScript
xxxxxxxxxx
1
import { Injectable } from '@angular/core';
2
import { HttpClient } from '@angular/common/http';
3
import { Observable } from 'rxjs';
4
5
@Injectable({
6
providedIn: 'root'
7
})
8
export class ApiService {
9
private url = "";
10
11
constructor(public http: HttpClient) {
12
}
13
14
getAllCompanies(pageNo,pageSize,sortOrder): Observable<any> {
15
this.url = 'http://localhost:59390/api/Pagination/getAllCompanies?pageNo=' + pageNo+'&pageSize='+pageSize+'&sortOrder='+sortOrder;
16
return this.http.get(this.url);
17
}
18
19
getAllCompaniesCount(): Observable<any> {
20
this.url = 'http://localhost:59390/api/Pagination/getAllCompaniesCount';
21
return this.http.get(this.url);
22
}
23
}
Шаг 6
Это наиболее важный файл, поскольку я отделил логику от логики разбиения на страницы, чтобы было очень легко повторно использовать один и тот же код, а не писать его каждый раз.
Скопируйте приведенный ниже код и замените его файлом pagination.service.ts.
JavaScript
xxxxxxxxxx
1
import { Injectable } from '@angular/core';
2
import { CompaniesPerPage } from './CompaniesPerPage';
3
4
@Injectable()
5
6
export class PaginationService {
7
//Pagination Variables
8
9
pageNumberPerPage = 0;
10
pageNumberShow = CompaniesPerPage.displayNoOfPagesPerPage;
11
temppage: number = 0;
12
disabledNextBtn: boolean;
13
disabledPrevBtn: boolean = true;
14
pageField = [];
15
exactPageList: any;
16
prevtrue: boolean;
17
nexttrue: boolean;
18
currentPage = 1;
19
pageNumber: boolean[] = [];
20
showNoOfCurrentPage: any = 1;
21
showPageOnlyOntabsChange: boolean = true;
22
lastPage: any = 0;
23
24
constructor() {
25
}
26
27
// On page load
28
pageOnLoad() {
29
if (this.temppage == 0 ) {
30
31
this.pageField = [];
32
for (var a = 0; a < this.pageNumberShow; a++) {
33
this.pageField[a] = this.temppage + 1;
34
this.temppage = this.temppage + 1;
35
if (this.exactPageList == this.pageField[a]) {
36
for (var b = 0; b < this.pageNumberShow - 7; b++) {
37
if (a == b) {
38
this.temppage = this.temppage - (b + 1);
39
this.prevtrue = false;
40
break;
41
}
42
}
43
this.disabledNextBtn = true;
44
break;
45
} else {
46
this.disabledNextBtn = false;
47
}
48
}
49
}
50
}
51
52
prevCompanies() {
53
54
this.pageNumber[0] = true;
55
this.nexttrue = true;
56
if (this.showNoOfCurrentPage != 1) {
57
this.disabledNextBtn = false;
58
this.showNoOfCurrentPage = this.showNoOfCurrentPage - 1;
59
if (this.prevtrue) {
60
if (this.lastPage == 0) {
61
this.temppage = this.temppage - 10;
62
this.prevtrue = false;
63
} else {
64
this.temppage = this.lastPage ;
65
this.nexttrue =false;
66
this.prevtrue = false;
67
this.lastPage = 0;
68
}
69
}
70
for (var a = this.pageNumberShow - 1; a >= 0; a--) {
71
this.pageField[a] = this.temppage;
72
this.temppage = this.temppage - 1;
73
}
74
if (this.temppage == 0) {
75
this.showPageOnlyOntabsChange = false;
76
}
77
this.currentPage = this.pageField[0];
78
}
79
}
80
81
nextCompanies() {
82
83
if (this.disabledNextBtn == false) {
84
this.disabledPrevBtn = false;
85
this.pageField = [];
86
this.prevtrue = true;
87
this.showNoOfCurrentPage = this.showNoOfCurrentPage + 1;
88
this.pageNumber[0] = true;
89
if (this.nexttrue) {
90
this.temppage = this.temppage + 10;
91
this.nexttrue = false;
92
}
93
for (var a = 0; a < this.pageNumberShow; a++) {
94
this.pageField[a] = this.temppage + 1;
95
this.temppage = this.temppage + 1;
96
if (this.exactPageList == this.pageField[a]) {
97
this.lastPage = this.pageField[a];
98
this.lastPage = this.lastPage - (a + 1);
99
for (var b = 0; b < this.pageNumberShow - 7; b++) {
100
if (a == b) {
101
this.temppage = this.temppage - (b + 1);
102
103
//this.prevtrue = false;
104
break;
105
}
106
}
107
this.disabledNextBtn = true;
108
break;
109
} else {
110
this.disabledNextBtn = false;
111
}
112
}
113
this.currentPage = this.pageField[0];
114
}
115
}
116
117
}
С помощью описанных выше шагов наше кодирование завершено, так что теперь пришло время проверить вывод с помощью команды ng serve -o
.
Здесь на этих изображениях мы видим, что общее количество записей составляет 60, но мы отображаем только 5 записей на странице с общим количеством кнопок 12 страниц.
Вот как работает логика:
Заключение
В этой статье я попытался объяснить, как отображать выбранное количество записей на страницу, а также кнопки «следующий» и «предыдущий», используя нумерацию на стороне сервера в Angular 8 и веб-API ASP.NET.
Это вторая часть серверной нумерации страниц. В моей следующей статье из этой серии мы узнаем, как получать данные, щелкая заголовок и отображая его в разбивке по страницам.
Дальнейшее чтение
Почему большинство программистов неправильно разбивают на страницы