AngularJS + ASP.NET MVC 中的服务器端分页
本文介绍如何在 ASP.Net MVC Web 应用程序中实现 AngularJS 服务器端分页。
引言
本文介绍如何在 ASP.NET MVC Web 应用程序中使用 angular-utils-pagination(由 michaelbromley 提供)和 PageList(由 Troy Goode 提供)创建分页。
i. https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
ii. https://github.com/TroyGoode/PagedList
背景
此分页方法的基本思想是,不是获取所有页面的数据,而是仅在用户点击“下一页”按钮时通过 ajax 获取特定页面所需的数据。
服务器端分页方法的优点
- 对于大型数据集,效率更高(只需要该页面的数据集)。
- 初始加载速度更快。
- 不会出现内存不足的问题,因为浏览器只存储特定页面的数据集。
使用代码
基本设置
创建一个 ASP.Net Web 应用程序项目。
选择 MVC
成功创建项目后,打开“管理 NuGet 包”。
在“管理 NuGet 包”屏幕上,搜索 AngularJS 并安装。
接下来,在 NuGet 包屏幕上搜索 Troy Goode 提供的 PageList(https://github.com/TroyGoode/PagedList),然后单击“安装”。
然后导航到 https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination 并下载文件 dirPagination.js 和 dirPagination.tpl.html。
或者您可以使用 Bower 安装
bower install angular-utils-pagination
或者 npm
npm install angular-utils-pagination
现在文件设置已完成,我们可以开始编码了。
在这里,我们创建了一个名为“添加分页”的页面,并将拥有服务器端的一系列菜肴列表。
服务器端 C#
为了简单起见,我将使用硬编码列表作为示例,但是实际使用中它可以从数据库中检索。
//
// Model to store the list
//
public class DishesModel
{
public List<string> Dishes_List { get; set; }
// Pagination
public int? Page { get; set; }
public int TotalDishesCount { get; set; }
public IPagedList<string> DishesPageList { get; set; }
}
//
// This part could be a web api or in the MVC controller
//
public JsonResult dishesPagination(int? Page)
{
int pageSize = 10;
int pageNumber = (Page ?? 1);
if (Page > 0)
{
dishes_model.Page = Page;
}
List<string> dishes = new List<string>();
DishesModel dishes_model = new DishesModel();
// Hardcoded list for simplicity, it could be from database
for (int i = 1; i < 100; i++)
{
dishes.Add("noodles");
dishes.Add("sausage");
dishes.Add("beans on toast");
dishes.Add("cheeseburger");
dishes.Add("battered mars bar");
dishes.Add("crisp butty");
dishes.Add("yorkshire pudding");
dishes.Add("wiener schnitzel");
dishes.Add("sauerkraut mit ei");
dishes.Add("onion soup");
dishes.Add("bak choi");
dishes.Add("avacado maki");
}
dishes_model.Dishes_List = dishes;
dishes_model.TotalDishesCount = dishes_model.Dishes_List.Count();
dishes_model.DishesPageList = dishes_model.Dishes_List.ToPagedList(pageNumber, pageSize);
return Json(dishes_model);
}
Html
@{ ViewBag.Title = "Add Pagination"; } <h2>Add Pagination</h2> <div ng-app="myApp" ng-cloak> <div ng-controller="addPaginationCtrl"> <!-- Dishes Table --> <div class="table-responsive table-Item"> <table class="table table-bordered"> <thead> <tr> <th style="text-align:center;" width="10%">#</th> <th>Dish Name</th> </tr> </thead> <tbody> <!-- Loading message --> <tr ng-show="showLoading"> <td colspan="2"> <div><b>{{LoadingText}}</b></div> </td> </tr> <tr dir-paginate="idx in dishesPageList | itemsPerPage:itemsPerPage" total-items="total_count" pagination-id="dishesPagination"> <td>{{itemsPerPage *(pageno-1)+$index+1}}</td> <td>{{idx}}</td> </tr> </tbody> </table> <div align="right"> <dir-pagination-controls max-size="8" direction-links="true" boundary-links="true" pagination-id="dishesPagination" on-page-change="getData(newPageNumber)"> </dir-pagination-controls> </div> </div> </div> </div> <!--angular-utils-pagination library--> <script src="~/Scripts/AngularPagination/dirPagination.js"></script>
Javascript
<script>
(function ($) {
'use strict';
// Injects "angularUtils.directives.dirPagination" dependency
angular.module("myApp", ["angularUtils.directives.dirPagination"]);
angular.module("myApp").controller("addPaginationCtrl", ["$scope", "addPaginationService", function ($scope, addPaginationService) {
// Initialize variable
$scope.itemsPerPage = 10;
$scope.pageno = 1;
$scope.total_count = 0;
$scope.dishesPageList = [];
// This would fetch the data on page change.
$scope.getData = function (pageno) {
// Proceed to search function once validation success
$scope.LoadingText = "Loading Dishes...";
$scope.showLoading = true;
// Resets page list and total count on each page change
$scope.dishesPageList = [];
$scope.total_count = 0;
// Assign new page number
$scope.pageno = pageno;
addPaginationService.searchDishesPage(pageno)
.then(function (result) {
// if total dish count more than zero hides the loading text
if (result.TotalDishesCount > 0) {
$scope.showLoading = false;
}
else {
$scope.LoadingText = "Dishes not available.";
$scope.showLoading = true;
};
// Assigns total count and page list
$scope.total_count = result.TotalDishesCount;
$scope.dishesPageList = result.DishesPageList;
}, function () {
// error
$scope.LoadingText = "Error occur, please try again.";
$scope.showLoading = true;
}).finally(function () {
// called no matter success or failure
});
};
// Initial load set to page 1
$scope.getData(1);
}]);
angular.module("myApp").factory("addPaginationService", ["$http", function ($http) {
var service = {};
var dishesList = [];
service.getDishesList = function () {
return dishesList;
};
// Ajax call to server to retrieve dishes data based on page number
service.searchDishesPage = function (pageno) {
var model = {
Page: pageno
}
return $http({
method: "POST",
url: '@Url.Action("dishesPagination", "Home")',
headers: { 'Content-Type': 'application/json; charset=utf-8' },
data: model
}).then(
function successCallback(response) {
dishesList = response.data.DishesPageList;
return response.data;
},
function errorCallback(response) {
console.log("Search Dishes Error:" + response);
// May add exception code
});
};
return service;
}]);
})(jQuery);
</script>
测试应用
编译并执行 Web 应用程序。
演示网站:http://mytutorial.yolio.my.tmp13.mschosting.com/home/addpagination
关注点
学习如何在 AngularJS 中实现 ASP.Net MVC 分页。
历史
- 2016 年 8 月 13 日:第一个版本