目录
介绍
这是由三篇文章组成的系列文章,在本文中,我们将显示记录数,并以此来计算页面数,但是在一页中,我们只能看到选定的记录,而不是一次获取所有记录,我们将基于页面获取记录,这将提高我们的性能。
如何工作?
假设我们有500条记录要在前端显示,并且每页只显示100条记录,那么在单击第2页后,它将显示下100条记录,依此类推。在Angular中,我们可以使用管道并安装一些软件包来显示分页,但是在这里,如果一次只显示100条记录,那为什么要提取全部500条记录呢?这会降低我们的性能。
因此,最好是一次只获取100条记录,而当您单击下一页时,它将获取该特定页面的下100条记录。在这里,每次您单击页面时,它将从数据库表中获取记录。
先决条件
- Angular的基础知识
- 必须安装Visual Studio Code
- 必须安装Angular CLI
- 必须安装Node JS
- 必须安装Microsoft Visual Studio 2017
- SQL Server 2014。
使用代码
后端
在这里,我们将使用SQL Server执行与后端相关的代码。
第一步是创建数据库。
步骤1
create database company
让我们在本地SQL Server上创建一个数据库。我希望您已经在计算机上安装了SQL Server 2017(也可以使用SQL Server 2008、2012或2016)。
步骤2
通过使用以下代码创建CompanyDetails表:
CREATE TABLE [dbo].[CompanyDetails](
[CompanyId] [int] IDENTITY(1,1) NOT NULL,
[CompanyName] [nvarchar](100) NULL,
[City] [nvarchar](50) NULL,
[State] [nvarchar](50) NULL,
[Owner] [nvarchar](50) NULL,
[PublishYear] [int] NULL,
CONSTRAINT [PK_CompanyDetails] PRIMARY KEY CLUSTERED
(
[CompanyId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, _
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
现在,让我们添加存储过程。
步骤3
创建以下存储过程:
GetAllCompanies
Create Proc [dbo].[Usp_GetAllCompanies]
@PageNo INT ,
@PageSize INT ,
@SortOrder VARCHAR(200)
As
Begin
Select * From (Select ROW_NUMBER() Over (
Order by CompanyName ) AS 'RowNum', *
from [CompanyDetails]
)t where t.RowNum Between ((@PageNo-1)*@PageSize +1) AND (@PageNo*@pageSize)
End
GetAllCompaniesCount
Create Proc [dbo].[Usp_getAllCompaniesCount]
As
Begin
select count(CompanyId) from [CompanyDetails]
End
Web API
创建一个ASP.NET Core应用程序。
请按照以下步骤创建ASP.NET Core应用程序。
步骤1
在Visual Studio 2019中,单击文件 -> 新建 -> 项目。
步骤2
选择“创建”选项,然后选择“ASP.NET Web应用程序”。
步骤3
选择Web API,然后单击确定。
步骤4
现在,右键单击控制器,然后添加一个新项目。
步骤5
选择ADO.NET实体数据模型,然后单击添加。
步骤6
下一步是EF Designer,只需单击“下一步”。
步骤7
将显示一个新的弹出窗口。点击下一步。如果您的未建立,请单击新连接。
步骤8
复制数据库连接服务器名称,并将其粘贴到服务器名称textbox中。您将看到所有数据库,选择数据库,然后单击OK。
步骤9
将显示下一个弹出窗口,粘贴您的数据库服务器名称,然后选择数据库并测试连接,然后单击Next。在这里,在新屏幕中,选择表和存储过程。然后点击完成。
我们的下一步是右键单击controllers文件夹并添加一个新的控制器。将其命名为“Paginationcontroller”,然后在中添加以下名称空间Paginationcontroller。
这是获取所有分页记录的完整代码。
完整的分页控制器代码
using System.Collections.Generic;
using System.Data.Entity.Core.Objects;
using System.Linq;
using System.Web.Http;
using Pagination.Models;
namespace Pagination.Controllers
{
public class PaginationController : ApiController
{
CompanyEntities2 db = new CompanyEntities2();
[HttpGet]
public object getAllCompanies(int pageNo, int pageSize, string sortOrder)
{
var oMyString = new ObjectParameter("totalCount", typeof(int));
var companyDetails = db.Usp_GetAllCompanies(pageNo, pageSize, sortOrder).ToList();
return companyDetails;
}
[HttpGet]
public object getAllCompaniesCount()
{
var companyDetailsCount = db.Usp_getAllCompaniesCount().SingleOrDefault();
return companyDetailsCount;
}
}
}
前端
步骤1
让我们使用以下npm命令创建一个Angular项目:
ng new pagination
步骤2
在Visual Studio code中打开新创建的项目并在项目中install bootstrap:
npm install bootstrap --save
现在打开styles.css文件并添加Bootstrap文件引用。要在styles.css文件中添加引用,请添加以下行:
@import '~bootstrap/dist/css/bootstrap.min.css';
步骤3
现在,使用以下命令创建一个新组件:
ng g c pagination
步骤4
现在,使用以下命令创建新服务:
ng generate service pagination
步骤5
现在打开pagination.component.html并粘贴以下代码以查看HTML模板。
<div class="row">
<div class="col-12 col-md-12">
<div class="card">
<div class="card-header">
Companies 1-{{pageSize}} (Total:{{totalCompaniesCount}})
</div>
<div class="card-body position-relative">
<div class="table-responsive cnstr-record companie-tbl">
<table class="table table-bordered heading-hvr">
<thead>
<tr>
<th style="cursor: pointer;" [ngClass]="order =='CompanyNumber'? 'active':''"
(click)="setOrder('CompanyNumber')" width="80">Company Name.</th>
<th style="cursor: pointer;" [ngClass]="order =='CompanyType'? 'active':''"
(click)="setOrder('CompanyType')" width="75">City</th>
<th [ngClass]="order =='CompanyName'? 'active':''" style="cursor: pointer;"
(click)="setOrder('CompanyName')">State
</th>
<th [ngClass]="order =='OrgNo'? 'active':''"
style="cursor: pointer;" (click)="setOrder('OrgNo')"
width="75">Owner
</th>
<th [ngClass]="order =='Street'? 'active':''"
style="cursor: pointer; width:250px"
(click)="setOrder('Street')">Publish Year</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of companies">
<td>{{item.CompanyName}}</td>
<td>{{item.City}}</td>
<td>{{item.State}}</td>
<td>{{item.Owner}}</td>
<td>{{item.PublishYear}}</td>
</tr>
</tbody>
</table>
</div>
<!-- Code by pagination -->
<div class="container mw-100">
<div class="row">
<div class="col-md-3"> </div>
<div *ngIf="companies !=0" class="col-md-6">
<ul class="pagination justify-content-center">
<li *ngFor="let page of pageField;let i=index" class="page-item">
<a (click)="showCompaniesByPageNumber(page,i)"
[ngClass]="pageNumber[i] ? 'pageColor':'page-link'"
style=" margin-right: 5px;;margin-top: 5px">{{page}}
</li>
</ul>
<div style="text-align: center;">
Page {{currentPage}} of Total page {{paginationService.exactPageList}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
步骤6
之后,打开pagination.component.ts文件,并将以下代码添加到已编写我们逻辑的文件中。
import { Component, OnInit } from '@angular/core';
import { ApiService } from './api.service';
import { PaginationService } from './pagination.service';
@Component({
selector: 'app-pagination',
templateUrl: './pagination.component.html',
styleUrls: ['./pagination.component.css']
})
export class PaginationComponent implements OnInit {
companies = [];
pageNo: any = 1;
pageNumber: boolean[] = [];
sortOrder: any = 'CompanyName';
//Pagination Variables
pageField = [];
exactPageList: any;
paginationData: number;
companiesPerPage: any = 5;
totalCompanies: any;
totalCompaniesCount: any;
constructor(public service: ApiService, public paginationService: PaginationService) { }
ngOnInit() {
this.pageNumber[0] = true;
this.paginationService.temppage = 0;
this.getAllCompanies();
}
getAllCompanies() {
this.service.getAllCompanies
(this.pageNo, this.companiesPerPage, this.sortOrder).subscribe((data: any) => {
this.companies = data;
this.getAllCompaniesCount();
})
}
//Method For Pagination
totalNoOfPages() {
this.paginationData = Number(this.totalCompaniesCount / this.companiesPerPage);
let tempPageData = this.paginationData.toFixed();
if (Number(tempPageData) < this.paginationData) {
this.exactPageList = Number(tempPageData) + 1;
this.paginationService.exactPageList = this.exactPageList;
} else {
this.exactPageList = Number(tempPageData);
this.paginationService.exactPageList = this.exactPageList
}
this.paginationService.pageOnLoad();
this.pageField = this.paginationService.pageField;
}
showCompaniesByPageNumber(page, i) {
this.companies = [];
this.pageNumber = [];
this.pageNumber[i] = true;
this.pageNo = page;
this.getAllCompanies();
}
getAllCompaniesCount() {
this.service.getAllCompaniesCount().subscribe((res: any) => {
this.totalCompaniesCount = res;
this.totalNoOfPages();
})
}
}
步骤7
接下来打开pagination.component.css文件,并粘贴代码以进行某些样式设置。
@charset "utf-8";
/* CSS Document */
@media all{
*{padding:0px;margin:0px;}
div{vertical-align:top;}
img{max-width:100%;}
html {-webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;}
body{overflow:auto!important; width:100%!important;}
html, body{background-color:#e4e5e6;}
html {position:relative; min-height:100%;}
.card{border-radius:4px;}
.card-header:first-child {border-radius:4px 4px 0px 0px;}
/*Typekit*/
html, body{font-family:'Roboto', sans-serif; font-weight:400; font-size:13px;}
body{padding-top:52px;}
p{font-family:'Roboto', sans-serif; color:#303030; font-weight:400; margin-bottom:1rem;}
input, textarea, select{font-family:'Roboto', sans-serif;}
h1,h2,h3,h4,h5,h6{font-family:'Roboto', sans-serif; font-weight:700;}
h1{font-size:20px; color:#000000; margin-bottom:10px;}
h2{font-size:30px;}
h3{font-size:24px;}
h4{font-size:18px;}
h5{font-size:14px;}
h6{font-size:12px;}
.row {margin-right:-8px; margin-left:-8px;}
.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;}
.card-header{background-color:#f0f3f5; border-bottom:1px solid #c8ced3;
font-size:13px; font-weight:600; color:#464646;
text-transform:uppercase; padding:.75rem 8px;}
.cnstr-record th{white-space:nowrap;padding:.45rem .2rem; font-size:13px;
border-bottom-width:0px!important;}
.cnstr-record thead{background:#f0f3f5;}
.cnstr-record .form-control{font-size:13px; padding:0px 0rem 0px 0.2rem;
height:calc(2rem + 2px);}
.cnstr-record select.form-control{padding-left:.05rem;}
.cnstr-record .table td, .cnstr-record .table th {vertical-align:middle;}
.cnstr-record .table td{padding:.3rem;}
.cnstr-record .table td h4{margin:0px;}
.wp-50{width:50px;}
.wp-60{width:60px;}
.wp-70{width:70px;}
.wp-80{width:80px;}
.wp-90{width:90px;}
.wp-100{width:100px;}
.mw-auto{min-width:inherit;}
.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;}
.expand-row img{vertical-align:top; position:relative; top:2px;}
.sub-table th{font-weight:400; font-size:12px;}
.sub-table td{background:#efefef;}
.no-bg td{background:inherit;}
.mw-100{max-width:100%;}
.activeTabColor{
color: #fff;
background-color: #000000;
}
.page-item:first-child .page-link {
margin-left: 0;
border-top-left-radius: .25rem;
border-bottom-left-radius: .25rem;
}
.pageColor{
position: relative;
display: block;
padding: .5rem .75rem;
margin-left: -1px;
line-height: 1.25;
color: white!important;
background-color: black!important;
border: 1px solid #dee2e6;
}
.notAllowed{
position: relative;
display: block;
padding: .5rem .75rem;
margin-left: -1px;
line-height: 1.25;
color: #007bff;
background-color: #fff;
border: 1px solid #dee2e6;
cursor: not-allowed;
}
.page-link {
position: relative;
display: block;
padding: .5rem .75rem;
margin-left: -1px;
line-height: 1.25;
color: #007bff;
background-color: #fff;
border: 1px solid #dee2e6;
}
}
步骤8
最后,打开pagination.service.ts文件并添加服务以调用我们的API。
import { Injectable } from '@angular/core';
@Injectable()
export class PaginationService {
//Pagination Variables
temppage: number = 0;
pageField = [];
exactPageList: any;
constructor() {
}
// On page load
pageOnLoad() {
if (this.temppage == 0) {
this.pageField = [];
for (var a = 0; a < this.exactPageList; a++) {
this.pageField[a] = this.temppage + 1;
this.temppage = this.temppage + 1;
}
}
}
}
步骤9
让我们在api.service.ts文件中添加以下代码:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ApiService {
private url = "";
constructor(public http: HttpClient) {
}
getAllCompanies(pageNo,pageSize,sortOrder): Observable<any> {
this.url = 'http://localhost:59390/api/Pagination/getAllCompanies?pageNo=' +
pageNo+'&pageSize='+pageSize+'&sortOrder='+sortOrder;
return this.http.get(this.url);
}
getAllCompaniesCount(): Observable<any> {
this.url = 'http://localhost:59390/api/Pagination/getAllCompaniesCount';
return this.http.get(this.url);
}
}
步骤10
下一步也是要在您的项目中添加应用程序模块文件。
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ApiService } from './pagination/api.service';
import { HttpClientModule } from '@angular/common/http';
import { PaginationService } from './pagination/pagination.service';
import { PaginationComponent } from './pagination/pagination.component';
@NgModule({
declarations: [
AppComponent,
PaginationComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [ApiService,PaginationService],
bootstrap: [AppComponent]
})
export class AppModule { }
步骤11
现在是时候查看输出了,只需打开终端并输入“ng serve -o”即可在浏览器中自动编译并打开。
加载我们的页面后,您可以看到如下图所示的输出:
在这里,记录的总数为33,此基础上,我们的逻辑在前端将计算页数,即在一个页面中,我们只显示5条记录(可以更改),所以直到6 个页面,有每页有5条记录,这意味着现在只剩下3条记录,它将出现在最后一页,即第 7页。
第2页:要显示的记录总数为5。
在最后一页中,将仅显示3条记录。
通过这一步骤,我们已成功完成了前端、Web API和后端编码。
结论
在本文中,我试图解释如何获取记录,并在使用Angular8和ASP.NET的服务器端分页中显示记录。
这是服务器端分页的第1部分。
在我的下一篇文章或第2部分中,我们将学习如何添加“上一页”和“下一页”按钮,此外,我们将手动设置每页的记录总数。
我只是一个学习者,渴望学习新事物,与技术无关,而是各个方面。
"Never stop learning, because life never stops teaching" .....by Gautam Buddha。