65.9K
CodeProject 正在变化。 阅读更多。
Home

Angular UI-Grid 服务器端分页

starIconstarIconstarIconstarIconstarIcon

5.00/5 (8投票s)

2016年5月4日

CPOL

2分钟阅读

viewsIcon

57160

downloadIcon

1325

在这篇文章中,我将演示如何在 ASP.Net MVC 应用程序中使用带有服务器端分页的 Angular UI Grid。

引言

Angular UI Grid 是一个用于 AngularJS 的数据网格,无需 JQuery,可以处理大数据,是 Angular UI 套件的一部分。

背景

最近,我正在寻找一个具有排序、过滤、分页、内联编辑器、响应式设计和其他高级功能等组件的数据表。我尝试集成和使用 Jquery datatable(Angular),但当我尝试在行点击/行选择按钮点击时传递整行数据时,问题出现了。

在渲染时,它无法传递 angular 对象(只能传递 int、string、boolean),这对我来说是一个大问题,因为我在应用程序前端使用 AngularJS。

我决定更改整个表格,找到了 Angular UI Grid。让我们开始吧:

如我们所知,Angular UI Grid 是 Angular UI 的一部分,因此我们有一些便利。在使用它之前,我们需要下载/安装包。

要下载包,请访问 URL:http://ui-grid.info

SQL 数据库

CREATE TABLE [dbo].[tblProducts](
	[ProductID] [int] NOT NULL,
	[ProductTitle] [nvarchar](256) NULL,
	[Type] [nvarchar](50) NULL,
	[Price] [numeric](18, 2) NULL,
	[CreatedOn] [datetime] NULL,
 CONSTRAINT [PK_tblProducts] PRIMARY KEY CLUSTERED 
(
	[ProductID] 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

演示数据

INSERT INTO [tblProducts]
SELECT 1,'Ape Lifestyle Cotton Casual T-Shirt - Gray','Clothing',270.00,getdate()
Union All
SELECT 2,'Cotton Casual Short Sleeve Polo - White','Clothing',790.50,getdate()
Union All
SELECT 3,'Cotton Casual Shirt - Sky Blue and White Stripe','Clothing',1555.00,getdate()
Union All
SELECT 4,'Cotton Mix Casual Panjabi - Thistle and Gray Stripe','Clothing',2458.00,getdate()
Union All
SELECT 5,'Cotton Mix Casual Panjabi - Black and Purple Stripe','Clothing',2458.00,getdate()
Union All
SELECT 6,'Cotton Casual Shirt - Red and White Check','Clothing',1735.00,getdate()
Union All
SELECT 7,'Kingstar TITANS 1 i19 Smartphone 8GB - White','Smartphone',6300.00,getdate()
Union All
SELECT 8,'MyCell Spider A4 Smartphone 8GB – White','Smartphone',7770.00,getdate()
Union All
SELECT 9,'HTC One M9S Nano-SIM Smartphone 16GB - Silver','Smartphone',26900.00,getdate()
Union All
SELECT 10,'WE X1 Smartphone 16GB – Silver','Smartphone',18600.00,getdate()
Union All
SELECT 11,'Microsoft Lumia 540 Smartphone 8GB – Cyan','Smartphone',13999.00,getdate()
Union All
SELECT 12,'BlackBerry Z10 Smartphone 16GB - White','Smartphone',18000.00,getdate()
Union All
SELECT 13,'Ape Lifestyle Cotton Casual T-Shirt - Gray','Clothing',270.00,getdate()
Union All
SELECT 14,'Cotton Casual Short Sleeve Polo - White','Clothing',790.50,getdate()
Union All
SELECT 15,'Cotton Casual Shirt - Sky Blue and White Stripe','Clothing',1555.00,getdate()
Union All
SELECT 16,'Cotton Mix Casual Panjabi - Thistle and Gray Stripe','Clothing',2458.00,getdate()
Union All
SELECT 17,'Cotton Mix Casual Panjabi - Black and Purple Stripe','Clothing',2458.00,getdate()
Union All
SELECT 18,'Cotton Casual Shirt - Red and White Check','Clothing',1735.00,getdate()
Union All
SELECT 19,'Kingstar TITANS 1 i19 Smartphone 8GB - White','Smartphone',6300.00,getdate()
Union All
SELECT 20,'MyCell Spider A4 Smartphone 8GB – White','Smartphone',7770.00,getdate()
Union All
SELECT 21,'HTC One M9S Nano-SIM Smartphone 16GB - Silver','Smartphone',26900.00,getdate()
Union All
SELECT 22,'WE X1 Smartphone 16GB – Silver','Smartphone',18600.00,getdate()
Union All
SELECT 23,'Microsoft Lumia 540 Smartphone 8GB – Cyan','Smartphone',13999.00,getdate()
Union All
SELECT 24,'BlackBerry Z10 Smartphone 16GB - White','Smartphone',18000.00,getdate()

MVC 应用程序

让我们使用 Visual Studio 2015 创建一个新的演示应用程序。选择 MVC 和 Web API。点击确定

图:2

加载初始应用程序模板后,我们需要安装脚本包。我们需要使用 NuGet 包管理器安装两个包。首先,我们将安装 AngularJS,然后我们需要添加 Angular-Ui-Grid。在包管理器控制台中输入 Install-Package angularjs 成功安装后,输入 Install-Package angular-ui-grid

图:3

或者我们可以使用 NuGet 包管理器安装包

AngularJS

图:4

AngularJS-uigrid

图:5

我们的包已安装,现在我们需要向应用程序添加一个新的控制器并生成视图。在我们的主布局中,我们需要添加脚本库的引用。


图:6

在头部部分添加 ui 样式引用

图:7


AngularJS

让我们添加文件夹来创建 angular 脚本。

图:8

JS-模块

var app;
(function () {
    'use strict';
    app = angular.module('UIGrid_App',
        [
            'ngAnimate',                // support for CSS-based animations
            'ngTouch',                  //for touch-enabled devices
            'ui.grid',                  //data grid for AngularJS
            'ui.grid.pagination',       //data grid Pagination
            'ui.grid.resizeColumns',    //data grid Resize column
            'ui.grid.moveColumns',      //data grid Move column
            'ui.grid.pinning',          //data grid Pin column Left/Right
            'ui.grid.selection',        //data grid Select Rows
            'ui.grid.autoResize',       //data grid Enabled auto column Size
            'ui.grid.exporter'          //data grid Export Data
        ]);
})();

JS-控制器

app.controller('ProductsCtrl', ['$scope', 'CRUDService', 'uiGridConstants',
    function ($scope, CRUDService, uiGridConstants) {
        $scope.gridOptions = [];

        //Pagination
        $scope.pagination = {
            paginationPageSizes: [15, 25, 50, 75, 100, "All"],
            ddlpageSize: 15,
            pageNumber: 1,
            pageSize: 15,
            totalItems: 0,

            getTotalPages: function () {
                return Math.ceil(this.totalItems / this.pageSize);
            },
            pageSizeChange: function () {
                if (this.ddlpageSize == "All")
                    this.pageSize = $scope.pagination.totalItems;
                else
                    this.pageSize = this.ddlpageSize

                this.pageNumber = 1
                $scope.GetProducts();
            },
            firstPage: function () {
                if (this.pageNumber > 1) {
                    this.pageNumber = 1
                    $scope.GetProducts();
                }
            },
            nextPage: function () {
                if (this.pageNumber < this.getTotalPages()) {
                    this.pageNumber++;
                    $scope.GetProducts();
                }
            },
            previousPage: function () {
                if (this.pageNumber > 1) {
                    this.pageNumber--;
                    $scope.GetProducts();
                }
            },
            lastPage: function () {
                if (this.pageNumber >= 1) {
                    this.pageNumber = this.getTotalPages();
                    $scope.GetProducts();
                }
            }
        };

        //ui-Grid Call
        $scope.GetProducts = function () {
            $scope.loaderMore = true;
            $scope.lblMessage = 'loading please wait....!';
            $scope.result = "color-green";

            $scope.highlightFilteredHeader = function (row, rowRenderIndex, col, colRenderIndex) {
                if (col.filters[0].term) {
                    return 'header-filtered';
                } else {
                    return '';
                }
            };
            $scope.gridOptions = {
                useExternalPagination: true,
                useExternalSorting: true,
                enableFiltering: true,
                enableSorting: true,
                enableRowSelection: true,
                enableSelectAll: true,
                enableGridMenu: true,

                columnDefs: [
                    { name: "ProductID", displayName: "Product ID", width: '10%', headerCellClass: $scope.highlightFilteredHeader },
                    { name: "ProductTitle", title: "Product Title", width: '40%', headerCellClass: $scope.highlightFilteredHeader },
                    { name: "Type", title: "Type", headerCellClass: $scope.highlightFilteredHeader },
                    {
                        name: "Price", title: "Price", cellFilter: 'number',
                        filters: [{ condition: uiGridConstants.filter.GREATER_THAN, placeholder: 'Minimum' }, { condition: uiGridConstants.filter.LESS_THAN, placeholder: 'Maximum' }],
                        headerCellClass: $scope.highlightFilteredHeader
                    },
                    { name: "CreatedOn", displayName: "Created On", cellFilter: 'date:"short"', headerCellClass: $scope.highlightFilteredHeader },
                    {
                        name: 'Edit',
                        enableFiltering: false,
                        enableSorting: false,
                        width: '5%',
                        enableColumnResizing: false,
                        cellTemplate: '<span class="label label-warning label-mini">' +
                                      '<a href="" style="color:white" title="Select" ng-click="grid.appScope.GetByID(row.entity)">' +
                                        '<i class="fa fa-check-square" aria-hidden="true"></i>' +
                                      '</a>' +
                                      '</span>'
                    }
                ],
                exporterAllDataFn: function () {
                    return getPage(1, $scope.gridOptions.totalItems, paginationOptions.sort)
                    .then(function () {
                        $scope.gridOptions.useExternalPagination = false;
                        $scope.gridOptions.useExternalSorting = false;
                        getPage = null;
                    });
                },
            };

            var NextPage = (($scope.pagination.pageNumber - 1) * $scope.pagination.pageSize);
            var NextPageSize = $scope.pagination.pageSize;
            var apiRoute = 'api/Product/GetProducts/' + NextPage + '/' + NextPageSize;
            var result = CRUDService.getProducts(apiRoute);
            result.then(
                function (response) {
                    $scope.pagination.totalItems = response.data.recordsTotal;
                    $scope.gridOptions.data = response.data.productList;
                    $scope.loaderMore = false;
                },
            function (error) {
                console.log("Error: " + error);
            });
        }

        //Default Load
        $scope.GetProducts();

        //Selected Call
        $scope.GetByID = function (model) {
            $scope.SelectedRow = model;
        };
    }
]);

JS-服务

app.service('CRUDService', function ($http) {
    //**********----Get Record----***************
    this.getProducts = function (apiRoute) {
        return $http.get(apiRoute);
    }
});

Ui-Grid

在 index.cshtml 页面中添加 ui-grid 指令

图:9

加载器将在数据从服务器加载时显示加载消息。

图:10

在底部添加 angular 引用到页面

图:11

完整的 Ui 代码

@{
    ViewBag.Title = "Products";
}

<h3>Products with UI Grid</h3>

<div class="row">
    <div class="col-md-12" ng-controller="ProductsCtrl">
        <div ui-grid="gridOptions"
             ui-grid-resize-columns
             ui-grid-move-columns
             ui-grid-exporter
             ui-grid-selection
             ui-grid-pinning class="grid"></div>

        <div class="loadmore">
            <div ng-show="loaderMore" ng-class="result">
                <img src="~/Content/ng-loader.gif" />
                {{lblMessage}}
            </div>
        </div>

        <div role="contentinfo" class="ui-grid-pager-panel ng-scope">
            <div role="navigation" class="ui-grid-pager-container">
                <div role="menubar" class="ui-grid-pager-control">
                    <!-- Start Page -->
                    <button type="button" role="menuitem" class="ui-grid-pager-first" ui-grid-one-bind-title="aria.pageToFirst"
                            ui-grid-one-bind-aria-label="aria.pageToFirst"
                            ng-click="pagination.firstPage()"
                            ng-disabled="cantPageBackward()" title="Page to first" aria-label="Page to first"
                            disabled="disabled">
                        <div class="first-triangle">
                            <div class="first-bar"></div>
                        </div>
                    </button>

                    <!-- Prev Page -->
                    <button type="button" role="menuitem" class="ui-grid-pager-previous"
                            ui-grid-one-bind-title="aria.pageBack" ui-grid-one-bind-aria-label="aria.pageBack"
                            ng-click="pagination.previousPage()"
                            ng-disabled="cantPageBackward()" title="Page back" aria-label="Page back" disabled="disabled">
                        <div class="first-triangle prev-triangle"></div>
                    </button>

                    <input type="number" ui-grid-one-bind-title="aria.pageSelected" ui-grid-one-bind-aria-label="aria.pageSelected"
                           class="ui-grid-pager-control-input ng-pristine ng-untouched ng-valid ng-not-empty ng-valid-min ng-valid-max ng-valid-required"
                           ng-model="pagination.pageNumber"
                           min="1" max="{{pagination.getTotalPages()}}" required="" title="Selected page"
                           aria-label="Selected page" disabled>

                    <span class="ui-grid-pager-max-pages-number ng-binding"
                          ng-show="pagination.getTotalPages() > 0">
                        <abbr ui-grid-one-bind-title="paginationOf" title="of"> /</abbr>{{pagination.getTotalPages()}}
                    </span>

                    <!-- Next Page -->
                    <button type="button" role="menuitem" class="ui-grid-pager-next" ui-grid-one-bind-title="aria.pageForward"
                            ui-grid-one-bind-aria-label="aria.pageForward"
                            ng-click="pagination.nextPage()"
                            ng-disabled="cantPageForward()"
                            title="Page forward" aria-label="Page forward">
                        <div class="last-triangle next-triangle"></div>
                    </button>

                    <!-- Last Page -->
                    <button type="button" role="menuitem" class="ui-grid-pager-last"
                            ui-grid-one-bind-title="aria.pageToLast" ui-grid-one-bind-aria-label="aria.pageToLast"
                            ng-click="pagination.lastPage()" ng-disabled="cantPageToLast()" title="Page to last" aria-label="Page to last">
                        <div class="last-triangle"><div class="last-bar"></div></div>
                    </button>
                </div><!-- ngIf: grid.options.paginationPageSizes.length > 1 -->

                <div class="ui-grid-pager-row-count-picker ng-scope" @*ng-if="pagination.ddlpageSize.length > 1"*@>
                    <select ng-model="pagination.ddlpageSize"
                            ng-options="o as o for o in pagination.paginationPageSizes" ng-change="pagination.pageSizeChange()"
                            class="ng-pristine ng-untouched ng-valid ng-not-empty"></select>
                    <span class="ui-grid-pager-row-count-label ng-binding">&nbsp;items per page</span>
                </div>
                <!-- end ngIf: grid.options.paginationPageSizes.length > 1 -->
                <!-- ngIf: grid.options.paginationPageSizes.length <= 1 -->
            </div>
            <div class="ui-grid-pager-count-container">
                <div class="ui-grid-pager-count">
                    <span ng-show="pagination.totalItems > 0" class="ng-binding" style="">
                        {{pagination.pageNumber}}<abbr ui-grid-one-bind-title="paginationThrough" title="through"> - </abbr>{{pagination.ddlpageSize}} of {{pagination.totalItems}} items
                    </span>
                </div>
            </div>
        </div>

        <p>{{SelectedRow}}</p>
    </div>
</div>
@section AngularScript{
    <script src="~/ScriptsNg/Controllers/ProductsCtrl.js"></script>
    <script src="~/ScriptsNg/Service/CRUDService.js"></script>
}

模型:我们的 Ui 准备好了,让我们在我们的演示应用程序中创建一个新的模型。

图:12

我使用了 api 控制器从服务器获取数据,该数据将在分页操作时被调用。Api-控制器

[RoutePrefix("api/Product")]
public class ProductController : ApiController
{
private dbUIGrid_Entities _ctx = null;

[HttpGet, ResponseType(typeof(tblProduct)), Route("GetProducts/{pageNumber:int}/{pageSize:int}")]
public IHttpActionResult GetProducts(int pageNumber, int pageSize)
{
    List<tblProduct> productList = null; int recordsTotal = 0;
    try
    {
        using (_ctx = new dbUIGrid_Entities())
        {
            recordsTotal = _ctx.tblProducts.Count();
            productList = _ctx.tblProducts.OrderBy(x => x.ProductID)
                                    .Skip(pageNumber)
                                    .Take(pageSize)
                                    .ToList();
        }
    }
    catch (Exception)
    {
    }
    return Json(new
    {
        recordsTotal,
        productList
    });
}
}

最终输出  

图:13

过滤数据

图:14

希望这能帮到你:)

 

© . All rights reserved.