Вступление
В этой статье мы узнаем, как создавать пейджинг на стороне сервера, что очень полезно, когда нам нужно отобразить большое количество записей.
Эта статья будет заключительной частью нашей серии из трех частей. Вы можете проверить первую и вторую части, нажав на ссылки ниже:
Во второй части мы реализовали предыдущую и следующую кнопку. В этой последней части мы сортируем наши данные по кликам по заголовкам в порядке возрастания и убывания.
Итак, здесь мы показываем количество записей. При этом наша программа рассчитает количество страниц, но на одной странице мы можем видеть только выбранные записи, поэтому вместо выборки всех записей за один раз мы собираемся выбирать записи на основе страниц. Это увеличит нашу производительность.
Как это будет работать?
Во второй части мы работали над кнопками Prev и Next и их логикой. Здесь мы сортируем записи по возрастанию и убыванию, поэтому, когда мы щелкаем по имени столбца заголовка, он получает соответствующее количество записей в порядке по имени столбца.
Back End
Мы сделаем внутренний код, используя сервер SQL. В первой части мы уже создали базу данных и необходимые таблицы, поэтому нет необходимости создавать ее снова. Однако мы внесем небольшое изменение в хранимую процедуру. Таким образом, мы сортируем данные по возрастанию или по убыванию после нажатия на заголовки таблицы на экране. Для этого я использую операторы case, чтобы он управлял записями в соответствии с именем столбца.
SQL
xxxxxxxxxx
1
42
1
USE [Company]
2
GO
3
/****** Object: StoredProcedure [dbo].[Usp_GetAllCompanies] Script Date: 1/17/2020 11:05:09 PM ******/
4
SET ANSI_NULLS ON
5
GO
6
SET QUOTED_IDENTIFIER ON
7
GO
8
ALTER Proc [dbo].[Usp_GetAllCompanies]
9
@PageNo INT ,
10
@PageSize INT ,
11
@SortOrder VARCHAR(200)
12
As
13
Begin
14
15
Select * From (Select ROW_NUMBER() Over (
16
Order by
17
CASE WHEN @SortOrder = 'CompanyName_ASC' THEN CompanyName
18
END ASC,
19
CASE WHEN @SortOrder = 'CompanyName_DESC' THEN CompanyName
20
END DESC,
21
CASE WHEN @SortOrder = 'City_ASC' THEN City
22
END ASC,
23
CASE WHEN @SortOrder = 'City_DESC' THEN City
24
END DESC,
25
CASE WHEN @SortOrder = 'State_ASC' THEN [State]
26
END ASC,
27
CASE WHEN @SortOrder = 'State_DESC' THEN [State]
28
END DESC,
29
CASE WHEN @SortOrder = 'Owner_ASC' THEN [Owner]
30
END ASC,
31
CASE WHEN @SortOrder = 'Owner_DESC' THEN [Owner]
32
END DESC,
33
CASE WHEN @SortOrder = 'Year_ASC' THEN PublishYear
34
END ASC,
35
CASE WHEN @SortOrder = 'Year_DESC' THEN PublishYear
36
END DESC
37
38
) AS 'RowNum', *
39
from [CompanyDetails]
40
)t where t.RowNum Between ((@PageNo-1)*@PageSize +1) AND (@PageNo*@pageSize)
41
42
End
Внешний интерфейс
Это пошаговый процесс, при котором мы собираемся изменить часть кода в некоторых файлах, не тратя время на добавление компонентов и сервисов.
Шаг 1
Давайте скопируем этот HTML-код и заменим его в
файл pagination.html . Некоторое изменение по сравнению с предыдущей частью кода. Здесь мы добавляем новое событие click, называемое sortByHeading. По умолчанию он выбирает записи с названием компании в порядке возрастания. Если щелкнуть тот же заголовок, он снова попадет в API и извлечет записи в порядке убывания. Кроме того, я применяю CSS для цвета заголовка, поэтому, если вы щелкнете по другому заголовку, он будет извлекать записи на основе этого имени заголовка в порядке возрастания, и активный цвет будет применяться к этому конкретному заголовку.
HTML
xxxxxxxxxx
1
84
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
10
<div style="margin: auto;" class="add-row add-row-rel top-paging">
11
<span class="cpp">Companies per page:</span>
12
<a (click)="setRecPerPage(small)" [ngClass]="smallPageRow? 'active':'mr-2'">{{small}}</a>
13
<a (click)="setRecPerPage(medium)" [ngClass]="mediumPageRow? 'active':'mr-2'">{{medium}}</a>
14
<a (click)="setRecPerPage(large)" [ngClass]="largePageRow? 'active':'mr-2'">{{large}}</a>
15
</div>
16
</div>
17
18
</div>
19
<div class="card-body position-relative">
20
<div class="tbl-note-dentist">
21
Sort list by select <span>table headers</span>, click again to reorder
22
ascending/descending
23
</div>
24
<div class="table-responsive cnstr-record companie-tbl">
25
<table class="table table-bordered heading-hvr">
26
<thead>
27
<tr>
28
<th style="cursor: pointer;" [ngClass]="order =='CompanyName'? 'headActive':''"
29
(click)="sortByHeading('CompanyName')" width="80">Company Name.</th>
30
<th style="cursor: pointer;" [ngClass]="order =='City'? 'headActive':''"
31
(click)="sortByHeading('City')" width="75">City</th>
32
<th [ngClass]="order =='State'? 'headActive':''" style="cursor: pointer;"
33
(click)="sortByHeading('State')">State
34
</th>
35
<th [ngClass]="order =='Owner'? 'headActive':''" style="cursor: pointer;" (click)="sortByHeading('Owner')"
36
width="75">CEO
37
</th>
38
<th [ngClass]="order =='Year'? 'headActive':''" style="cursor: pointer; width:250px"
39
(click)="sortByHeading('Year')">Publish Year</th>
40
</tr>
41
</thead>
42
<tbody>
43
<tr *ngFor="let item of companies">
44
<td>{{item.CompanyName}}</td>
45
<td>{{item.City}}</td>
46
<td>{{item.State}}</td>
47
<td>{{item.Owner}}</td>
48
<td>{{item.PublishYear}}</td>
49
50
</tr>
51
</tbody>
52
</table>
53
54
55
</div>
56
<!-- Code by pagination -->
57
<div class="container mw-100">
58
<div class="row">
59
<div class="col-md-3"> </div>
60
<div *ngIf="companies !=0" class="col-md-6">
61
<ul class="pagination justify-content-center">
62
<li class="page-item">
63
<a (click)="showPrevCompanies()"
64
[ngClass]="(paginationService.showNoOfCurrentPage ==1)?'notAllowed':'page-link'"
65
style="margin-top: 5px; margin-right: 20px;cursor: pointer;">Prev</a></li>
66
<li *ngFor="let page of pageField;let i=index" class="page-item">
67
<a (click)="showCompaniesByPageNumber(page,i)" [ngClass]="pageNumber[i] ? 'pageColor':'page-link'"
68
style=" margin-right: 5px;;margin-top: 5px;cursor: pointer;">{{page}}</a>
69
70
</li>
71
<li class="page-item"><a (click)="showNextCompanies()"
72
[ngClass]="(paginationService.disabledNextBtn)?'notAllowed':'page-link'"
73
style="margin-top: 5px;margin-left: 20px; cursor: pointer;">Next</a> </li>
74
</ul>
75
<div style="text-align: center;">
76
Page {{currentPage}} of Total page {{paginationService.exactPageList}}
77
</div>
78
</div>
79
</div>
80
</div>
81
</div>
82
</div>
83
</div>
84
</div>
Шаг 2
В CSS-файле есть некоторые изменения, поэтому просто замените этот код на pagination.component.css .
CSS
xxxxxxxxxx
1
122
1
@charset "utf-8";
2
/* CSS Document */
3
@media all{
4
*{padding:0px;margin:0px;}
5
div{vertical-align:top;}
6
img{max-width:100%;}
7
html {font-smoothing:antialiased; osx-font-smoothing:grayscale;}
8
body{overflow:auto!important; width:100%!important;}
9
html, body{background-color:#e4e5e6;}
10
html {position:relative; min-height:100%;}
11
12
13
.card{border-radius:4px;}
14
.card-header:first-child {border-radius:4px 4px 0px 0px;}
15
16
/*Typekit*/
17
html, body{font-family:'Roboto', sans-serif; font-weight:400; font-size:13px;}
18
body{padding-top:52px;}
19
20
p{font-family:'Roboto', sans-serif; color:#303030; font-weight:400; margin-bottom:1rem;}
21
input, textarea, select{font-family:'Roboto', sans-serif;}
22
23
h1,h2,h3,h4,h5,h6{font-family:'Roboto', sans-serif; font-weight:700;}
24
h1{font-size:20px; color:#000000; margin-bottom:10px;}
25
h2{font-size:30px;}
26
h3{font-size:24px;}
27
h4{font-size:18px;}
28
h5{font-size:14px;}
29
h6{font-size:12px;}
30
31
.row {margin-right:-8px; margin-left:-8px;}
32
.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 {padding-right:8px; padding-left:8px;}
33
34
.card-header{background-color:#f0f3f5; border-bottom:1px solid #c8ced3; font-size:13px; font-weight:600; color:#464646; text-transform:uppercase; padding:.75rem 8px;}
35
36
37
.cnstr-record th{white-space:nowrap;padding:.45rem .2rem; font-size:13px; border-bottom-width:0px!important;}
38
.cnstr-record thead{background:#f0f3f5;}
39
40
.cnstr-record .form-control{font-size:13px; padding:0px 0rem 0px 0.2rem; height:calc(2rem + 2px);}
41
.cnstr-record select.form-control{padding-left:.05rem;}
42
.cnstr-record .table td, .cnstr-record .table th {vertical-align:middle;}
43
.cnstr-record .table td{padding:.3rem;}
44
.cnstr-record .table td h4{margin:0px;}
45
46
.wp-50{width:50px;}
47
.wp-60{width:60px;}
48
.wp-70{width:70px;}
49
.wp-80{width:80px;}
50
.wp-90{width:90px;}
51
.wp-100{width:100px;}
52
.mw-auto{min-width:inherit;}
53
.expand-row{width:100%; border:solid 1px #596269; display:inline-block; border-radius:3px; width:16px; height:16px; vertical-align:top; background:#596269; color:#ffffff!important;}
54
.expand-row img{vertical-align:top; position:relative; top:2px;}
55
.sub-table th{font-weight:400; font-size:12px;}
56
.sub-table td{background:#efefef;}
57
.no-bg td{background:inherit;}
58
.mw-100{max-width:100%;}
59
60
61
62
.activeTabColor{
63
color: #fff;
64
background-color: #000000;
65
}
66
.page-item:first-child .page-link {
67
margin-left: 0;
68
border-top-left-radius: .25rem;
69
border-bottom-left-radius: .25rem;
70
}
71
72
.pageColor{
73
position: relative;
74
display: block;
75
padding: .5rem .75rem;
76
margin-left: -1px;
77
line-height: 1.25;
78
color: white!important;
79
background-color: black!important;
80
border: 1px solid #dee2e6;
81
}
82
.notAllowed{
83
position: relative;
84
display: block;
85
padding: .5rem .75rem;
86
margin-left: -1px;
87
line-height: 1.25;
88
color: #007bff;
89
background-color: #fff;
90
border: 1px solid #dee2e6;
91
cursor: not-allowed;
92
}
93
.page-link {
94
position: relative;
95
display: block;
96
padding: .5rem .75rem;
97
margin-left: -1px;
98
line-height: 1.25;
99
color: #007bff;
100
background-color: #fff;
101
border: 1px solid #dee2e6;
102
}
103
104
.mr-2{
105
background-color: #007bff;
106
color: white!important;
107
margin: 5px;
108
padding: 5px;
109
cursor: pointer;
110
}
111
.active{
112
background-color: black;
113
color: white!important;
114
margin: 5px;
115
padding: 5px;
116
cursor: pointer;
117
}
118
.headActive{
119
color: red;
120
}
121
122
}
Шаг 3
Скопируйте приведенный ниже код и заменить его
pagination.component.ts
«ы
sortByHeading
метода.Машинопись
xxxxxxxxxx
1
158
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_ASC';
17
order:any='CompanyName';
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
orderBy: string='Asc';
33
34
totalCompanies: any;
35
totalCompaniesCount: any;
36
currentPage = 1;
37
38
constructor(public service: ApiService, public paginationService: PaginationService) { }
39
40
ngOnInit() {
41
this.pageNumber[0] = true;
42
this.paginationService.temppage = 0;
43
this.getAllCompanies();
44
}
45
getAllCompanies() {
46
this.service.getAllCompanies(this.pageNo, this.companiesPerPage, this.sortOrder).subscribe((data: any) => {
47
this.companies = data;
48
this.getAllCompaniesCount();
49
})
50
}
51
getAllCompaniesCount() {
52
this.service.getAllCompaniesCount().subscribe((res: any) => {
53
this.totalCompaniesCount = res;
54
this.totalNoOfPages();
55
})
56
}
57
58
//Method For Pagination
59
totalNoOfPages() {
60
61
this.paginationData = Number(this.totalCompaniesCount / this.companiesPerPage);
62
let tempPageData = this.paginationData.toFixed();
63
if (Number(tempPageData) < this.paginationData) {
64
this.exactPageList = Number(tempPageData) + 1;
65
this.paginationService.exactPageList = this.exactPageList;
66
} else {
67
this.exactPageList = Number(tempPageData);
68
this.paginationService.exactPageList = this.exactPageList
69
}
70
this.paginationService.pageOnLoad();
71
this.pageField = this.paginationService.pageField;
72
73
}
74
showCompaniesByPageNumber(page, i) {
75
this.companies = [];
76
this.pageNumber = [];
77
this.pageNumber[i] = true;
78
this.pageNo = page;
79
this.currentPage =page;
80
this.getAllCompanies();
81
}
82
83
//Pagination Start
84
85
showPrevCompanies() {
86
87
if (this.paginationService.showNoOfCurrentPage != 1) {
88
this.paginationService.prevCompanies();
89
this.pageNumber = [];
90
this.pageNumber[0] = true;
91
this.currentPage = this.paginationService.pageField[0];
92
this.getAllCompanies();
93
}
94
95
}
96
97
showNextCompanies() {
98
99
if (this.paginationService.disabledNextBtn == false) {
100
this.pageNumber = [];
101
this.paginationService.nextCompanies();
102
this.pageNumber[0] = true;
103
this.currentPage = this.paginationService.pageField[0];
104
this.getAllCompanies();
105
}
106
}
107
sortByHeading(value: string, id) {
108
this.companies = [];
109
this.sortOrder = value;
110
this.order =value;
111
if (this.orderBy == "Desc") {
112
this.orderBy = "Asc"
113
this.sortOrder =this.sortOrder+'_ASC';
114
} else {
115
this.orderBy = "Desc";
116
this.sortOrder =this.sortOrder+'_DESC'
117
}
118
this.getAllCompanies();
119
}
120
121
setRecPerPage(noOfRec) {
122
123
this.companies = [];
124
this.pageNumber = [];
125
this.pageNumber[0] = true;
126
this.paginationService.temppage = 0;
127
if (noOfRec == CompaniesPerPage.small) {
128
this.smallPageRow = true;
129
this.mediumPageRow = false;
130
this.largePageRow = false;
131
this.companiesPerPage = noOfRec;
132
this.currentPage = 1;
133
this.pageNumber[0] = true;
134
this.getAllCompanies();
135
136
}
137
else if (noOfRec == CompaniesPerPage.medium) {
138
this.smallPageRow = false;
139
this.mediumPageRow = true;
140
this.largePageRow = false;
141
this.companiesPerPage = noOfRec;
142
this.currentPage = 1;
143
this.pageNumber[0] = true;
144
this.getAllCompanies();
145
146
} else {
147
this.smallPageRow = false;
148
this.mediumPageRow = false;
149
this.largePageRow = true;
150
this.companiesPerPage = noOfRec;
151
this.currentPage = 1;
152
this.pageNumber[0] = true;
153
this.getAllCompanies();
154
155
}
156
//this.pageSize = page;
157
}
158
}
Шаг 6
Pagination.service.ts файл является тем же; никаких изменений здесь не требуется, но я все еще упоминаю об этом для справки.
Машинопись
xxxxxxxxxx
1
108
1
import {
2
Injectable
3
} from '@angular/core';
4
import {
5
CompaniesPerPage
6
} from './CompaniesPerPage';
7
@Injectable()
8
export class PaginationService {
9
//Pagination Variables
10
pageNumberPerPage = 0;
11
pageNumberShow = CompaniesPerPage.displayNoOfPagesPerPage;
12
temppage: number = 0;
13
disabledNextBtn: boolean;
14
disabledPrevBtn: boolean = true;
15
pageField = [];
16
exactPageList: any;
17
prevtrue: boolean;
18
nexttrue: boolean;
19
currentPage = 1;
20
pageNumber: boolean[] = [];
21
showNoOfCurrentPage: any = 1;
22
showPageOnlyOntabsChange: boolean = true;
23
lastPage: any = 0;
24
constructor() {}
25
// On page load
26
pageOnLoad() {
27
if (this.temppage == 0) {
28
this.pageField = [];
29
for (var a = 0; a < this.pageNumberShow; a++) {
30
this.pageField[a] = this.temppage + 1;
31
this.temppage = this.temppage + 1;
32
if (this.exactPageList == this.pageField[a]) {
33
for (var b = 0; b < this.pageNumberShow - 7; b++) {
34
if (a == b) {
35
this.temppage = this.temppage - (b + 1);
36
this.prevtrue = false;
37
break;
38
}
39
}
40
this.disabledNextBtn = true;
41
break;
42
} else {
43
this.disabledNextBtn = false;
44
}
45
}
46
}
47
}
48
prevCompanies() {
49
this.pageNumber[0] = true;
50
this.nexttrue = true;
51
if (this.showNoOfCurrentPage != 1) {
52
this.disabledNextBtn = false;
53
this.showNoOfCurrentPage = this.showNoOfCurrentPage - 1;
54
if (this.prevtrue) {
55
if (this.lastPage == 0) {
56
this.temppage = this.temppage - 10;
57
this.prevtrue = false;
58
} else {
59
this.temppage = this.lastPage;
60
this.nexttrue = false;
61
this.prevtrue = false;
62
this.lastPage = 0;
63
}
64
}
65
for (var a = this.pageNumberShow - 1; a >= 0; a--) {
66
this.pageField[a] = this.temppage;
67
this.temppage = this.temppage - 1;
68
}
69
if (this.temppage == 0) {
70
this.showPageOnlyOntabsChange = false;
71
}
72
this.currentPage = this.pageField[0];
73
}
74
}
75
nextCompanies() {
76
if (this.disabledNextBtn == false) {
77
this.disabledPrevBtn = false;
78
this.pageField = [];
79
this.prevtrue = true;
80
this.showNoOfCurrentPage = this.showNoOfCurrentPage + 1;
81
this.pageNumber[0] = true;
82
if (this.nexttrue) {
83
this.temppage = this.temppage + 10;
84
this.nexttrue = false;
85
}
86
for (var a = 0; a < this.pageNumberShow; a++) {
87
this.pageField[a] = this.temppage + 1;
88
this.temppage = this.temppage + 1;
89
if (this.exactPageList == this.pageField[a]) {
90
this.lastPage = this.pageField[a];
91
this.lastPage = this.lastPage - (a + 1);
92
for (var b = 0; b < this.pageNumberShow - 7; b++) {
93
if (a == b) {
94
this.temppage = this.temppage - (b + 1);
95
//this.prevtrue = false;
96
break;
97
}
98
}
99
this.disabledNextBtn = true;
100
break;
101
} else {
102
this.disabledNextBtn = false;
103
}
104
}
105
this.currentPage = this.pageField[0];
106
}
107
}
108
}
Кодирование сделано. Теперь пришло время проверить вывод с помощью команды
ng serve -o
. Заключение
Эта статья завершает полную серию серверной нумерации страниц. Я объяснил, как отображать выбранное количество записей на странице, а также следующую и предыдущую кнопки, применяя различные подходы и сортируя данные, используя щелчок по заголовку с помощью Angular 8 и ASP.NET.
Это третья часть серверной нумерации страниц.
This is the last part, so in the next article, we are going to learn new things. Time for some motivational quotes… «The secret of getting ahead is getting started». Last but not least, your feedback is very important so that I get a chance to improve myself. For that, I need your valuable comments. Good comments I will take as motivation and critique as the impetus for me to improve.
Please let me know if you liked and understood this article and how I could improve it. For any questions about this article regarding code or something, please leave a comment.