ABP之展现层(Datatables分页)

Posted 善良的小赵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ABP之展现层(Datatables分页)相关的知识,希望对你有一定的参考价值。

 在前面的随笔中,已经介绍了ABP的增删改查的操作,但是对于查询的数据并没有进行分页,只是进行粗糙的展示,今天的随笔中将摸索进行分页展示。这里打算使用的分页插件是DataTables,这是一款比较强大的表格插件。

在以前我们后台手动分页的时候,需要前台传入两个重要的分页参数:PageIndex和PageSize(显示第几页的数据和每页显示的数量),这是必须的量的参数。分页作为一个页面展示的基础功能,ABP框架已经对分页功能进行了一些方便性的操作,为我们提供了一些有助于分页的接口和Dto,Dto是什么?这个在前面的随笔中已经研究过了,这里就不再重复。

一 .ABP中的分页接口

在ABP中总共为我们提供了三个分页的接口:IPagedResultRequest、ISortedResultRequest、ILimitedResultRequest三个接口

 

从上面的三个接口中我们看到了三个重要的变量,这就是我们分页和排序中经常用到的量。

二. 实现分页的Dto

在我们免费的ABP中模板中,也就是只能找到这么三个接口,对我们分页来说确实并没有提供了多大的方便,但是在ABP Zero中已经对三个接口进行了相应的实现,只是zero是收费的。在这里我们可以模仿zero在我们ABP模板中添加上分页的Dto,并且为DataTables这个插件定制分页Dto。

 

详细的代码

 1 1.PagedInputDto
 2  public class PagedInputDto : IPagedResultRequest
 3     {
 4         /// <summary>
 5         /// 每页显示的行数
 6         /// </summary>
 7         [Range(1, AppConsts.MaxPageSize)]
 8         public int MaxResultCount { get; set; }
 9         /// <summary>
10         /// 跳过数量=MaxResultCount*页数
11         /// </summary>
12         [Range(0, int.MaxValue)]
13         public int SkipCount { get; set; }
14 
15         public PagedInputDto()
16         {
17             MaxResultCount = AppConsts.DefaultPageSize;
18         }
19     }
20 2. PagedAndFilteredInputDto
21     public class PagedAndFilteredInputDto : IPagedResultRequest
22     {
23         [Range(1, AppConsts.MaxPageSize)]
24         public int MaxResultCount { get; set; }
25 
26         [Range(0, int.MaxValue)]
27         public int SkipCount { get; set; }
28 
29         public string Filter { get; set; }
30 
31         public PagedAndFilteredInputDto()
32         {
33             MaxResultCount = AppConsts.DefaultPageSize;
34         }
35     }
36 3. PageAndSortedInputDto
37     public class PagedAndSortedInputDto : PagedInputDto, ISortedResultRequest
38     {
39         public string Sorting { get; set; }
40 
41         public PagedAndSortedInputDto()
42         {
43             MaxResultCount = AppConsts.DefaultPageSize;
44         }
45     }
46 4.PagedSortedAndFilteredInputDto
47     public class PagedSortedAndFilteredInputDto : PagedAndSortedInputDto
48     {
49         public string Filter { get; set; }
50         //接收DataTables的参数
51         public int Draw { get; set; }
52         public int Length
53         {
54             get
55             {
56                 return this.MaxResultCount;
57             }
58 
59             set
60             {
61                 this.MaxResultCount = value;
62             }
63         }
64         public int Start
65         {
66             get
67             {
68                 return this.SkipCount;
69             }
70 
71             set
72             {
73                 this.SkipCount = value;
74             }
75         }
76     }
77 5.DataTablesPageOutPutDto
78    [Serializable]
79     public class DataTablesPagedOutputDto<T>:PagedResultDto<T>
80     {
81         public int Draw { get; set; }
82 
83         /// <summary>
84         /// 过滤后的记录数(没有就是全部),这个是必须的参数
85         /// </summary>
86         public int RecordsFiltered { get; set; }
87 
88         public int RecordsTotal { get { return this.TotalCount; } }
89       
90         public DataTablesPagedOutputDto(int totalCount, IReadOnlyList<T> items)
91           : base(totalCount, items)
92         {
93             this.RecordsFiltered = totalCount;
94         }
95     }

 

其中PagedSortedAndFilteredInputDto和DataTablesPageOutPutDto分别是为了适应DataTables的需求定制的两个类,Input的类中Start、Length、Draw、Filter都是为了接收DataTables传递过来的参数,在OutPut类中定义了RecordsFiltered和recordsTotal和Draw这些都是DataTables需要的参数。说了这么多,还是先看一下DataTables这插件再说。

三.DataTables分页

在这里我们使用的服务端分页,详细的内容可查看官网的具体介绍:http://www.datatables.club/manual/server-side.html

(1)Dto的请求参数

当然参数还有许多,但是主要的参数也就是上面的那几个,尤其是已经圈出来的这三个,就可以完成分页功能了,如果需要进行排序或者添加按照字段的搜索的功能,那么就需要用到下面的字段了,我们这里只是使用分页功能。

(2)Dto的返回参数

 

 通过了上面DataTables官网的介绍,我们已经清楚了我们Dto中定义的参数的作用了,不知道大家有没有一点困惑,就是Draw参数到底是干什么的???哈哈哈,我们在DataTables中已经找到了答案,他是防止跨站脚本攻击的,关于他的赋值,只要给他赋值一个整数就可以了。

三.在ABP中使用DataTables实现分页

View

Index的具体代码

@using Abp.Authorization.Users
@using StudyABPProject.Web.Startup
@model IList<StudyABPProject.Movie.Dto.MovieTicketDto>
@{
    ViewBag.CurrentPageName = PageNames.Movies; // The menu item will be active for this page.
}
@section scripts
    {
    <script src="~/lib/jquery-daterangepicker/daterangepicker.js" asp-append-version="true"></script>
    <script src="~/view-resources/Views/Movie/Index.js" asp-append-version="true"></script>

    <link href="~/lib/jquery-daterangepicker/daterangepicker.css" rel="stylesheet" />
    <link href="~/lib/datatables/jquery.dataTables.min.css" rel="stylesheet" />
    <script src="~/lib/datatables/jquery.dataTables.min.js"></script>
}

<div class="row clearfix">
    <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
        <div class="card">
            <div class="header">
                <h2>
                    @L("Movie")
                </h2>
                <ul class="header-dropdown m-r--5">
                    <li class="dropdown">
                        <a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
                            <i class="material-icons">more_vert</i>
                        </a>
                        <ul class="dropdown-menu pull-right">
                            <li><a id="RefreshButton" href="javascript:void(0);" class="waves-effect waves-block"><i class="material-icons">refresh</i>Refresh</a></li>
                        </ul>
                    </li>
                </ul>
            </div>
            <div class="body table-responsive">
                <button type="button" class="btn btn-primary  waves-effect  waves-float pull-right" data-toggle="modal" data-target="#MovieTicketCreateModal">
                    <i class="material-icons">添加</i>
                </button>
                <table id="MovieTable" name="MovieTable"></table>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="MovieTicketCreateModal" tabindex="-1" role="dialog" aria-labelledby="UserCreateModalLabel" data-backdrop="static">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title">
                    <span>@L("CreateMovieTicket")</span>
                </h4>
            </div>
            <div class="modal-body">
                <form name="movieCreateForm" role="form" novalidate class="form-validation">
                    <div class="tab-content">
                        <div role="tabpanel" class="tab-pane animated fadeIn active" id="create-user-details">
                            <div class="row clearfix" style="margin-top:10px;">
                                <div class="col-sm-12">
                                    <div class="form-group form-float">
                                        <div class="form-line">
                                            <input class="form-control" type="text" name="MovieName" required maxlength="256" minlength="2">
                                            <label class="form-label">@L("MovieName")</label>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="row clearfix">
                                <div class="col-sm-12">
                                    <div class="form-group form-float">
                                        <div class="form-line">
                                            <input type="text" name="MovieActor" class="form-control" required maxlength="256">
                                            <label class="form-label">@L("MovieActor")</label>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="row clearfix">
                                <div class="col-sm-12">
                                    <div class="form-group form-float">
                                        <div class="form-line">
                                            <input type="datetime" name="StartTime" class="form-control" required>
                                            @*<label class="form-label">@L("StartTime")</label>*@
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="row clearfix">
                                <div class="col-sm-12">
                                    <div class="form-group form-float">
                                        <div class="form-line">
                                            <input type="datetime" id="EndTime" name="EndTime" class="form-control">
                                            @*<label class="form-label">@L("EndTime")</label>*@
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="row clearfix">
                                <div class="col-sm-12">
                                    <div class="form-group form-float">
                                        <div class="form-line">
                                            <input type="number" id="Money" name="Money" class="form-control">
                                            <label class="form-label">@L("Money")</label>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default waves-effect" data-dismiss="modal">取消</button>
                        <button type="submit" id="btnSave" class="btn btn-primary waves-effect">保存</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
<div class="modal fade" id="MovieTicketEditModal" tabindex="-1" role="dialog" data-backdrop="static">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
        </div>
    </div>
</div>

 

Js

关于js代码的位置我也按照框架中的位置放在了view-resources,话说Js代码离View有点远~~~

Index.Js中的主要代码

(function () {
    $(function () {

        var _movieService = abp.services.app.movieTicket;
        var _$modal = $(\'#MovieTicketCreateModal\');
        var _$form = _$modal.find(\'form[name="movieCreateForm"]\');

        _$form.validate({
            rules: {
                MovieName:
                {
                    required:true
                },
                StartTime: "required",
                EndtTime:
                {
                    required: true
                },
                MovieActor: "required"
                ,Money:"required"
            },
            messages: {
                MovieName: {
                    required:"电影名称不能为空"
                },
                MovieActor: {
                    required: "演员名称不能为空"
                },
                StartTime: {
                    required: "开始时间不能为空"
                },
                EndTime: {
                    required: "结束时间不能为空"
                },
                Money: {
                    required: "票价不能为空"
                }
            }
        });

        var dateOption = {
            locale: {

                format: \'YYYY-MM-DD HH:mm:ss\',
                applyLabel: \'确认\',
                cancelLabel: \'取消\'

            },
            singleDatePicker: true,
            startDate: moment().format("YYYY-MM-DD HH:mm:ss"),
            timePicker24Hour: true,
            timePicker: true,
            autoApply: true,
            autoUpdateInput: true
        };
        $(\'input[name=StartTime]\').daterangepicker(dateOption);
        $(\'input[name=EndTime]\').daterangepicker(dateOption);
        $(\'#RefreshButton\').click(function () {
            refreshUserList();
        });
      
        $(\'.delete-movie\').click(function () {
            var movieId = $(this).attr("data-movie-id");
            var movieName = $(this).attr("data-movie-name");
            abp.message.confirm(
                "删除电影 \'" + movieName + "\'?",
                function (isConfirmed) {
                    if (isConfirmed) {
                        _movieService.deleteMovie({
                            "id": movieId, "movieName": movieName,
                        }).done(function () {
                            refreshMovieList();
                        });
                    }
                }
            );
        });

        $(\'.edit-movie\').click(function (e) {
            var movieId = $(this).attr("data-movie-id");

            e.preventDefault();
            $.ajax({
                url: abp.appPath + \'MovieTicket/EditMovieTicketModal?movieId=\' + movieId,
                type: \'POST\',
                contentType: \'application/html\',
                success: function (content) {
                    $(\'#MovieTicketEditModal div.modal-content\').html(content);
                },
                error: function (e) { }
            });
        });

        _$form.find(\'button[type="submit"]\').click(function (e) {
            e.preventDefault();

            if (!_$form.valid()) {
                return;
            }

            var movie = _$form.serializeFormToObject(); 
            abp.ui.setBusy(_$modal);
            _movieService.createMovie(movie).done(function (response) {
                if (response == "No") {
                    abp.message.error("创建失败");
                }
                else {
                    _$modal.modal(\'hide\');
                    location.reload(true); 
                }
               
            }).always(function () {
                abp.ui.clearBusy(_$modal);
            });
        });

        _$modal.on(\'shown.bs.modal\', function () {
            _$modal.find(\'input:not([type=hidden]):first\').focus();
        });

        function refreshMovieList() {
            location.reload(true); //reload page to see new user!
        }

        function deleteUser(userId, userName) {
           
        }
        var CONSTANT = {
            DATA_TABLES: {
                DEFAULT_OPTION: { //DataTables初始化选项  
                    language: {
                        "sProcessing": "处理中...",
                        "sLengthMenu": "每页 _MENU_ 项",
                        "sZeroRecords": "没有匹配结果",
                        "sInfo": "当前显示第 _START_ 至 _END_ 项,共 _TOTAL_ 项。",
                        "sInfoEmpty": "当前显示第 0 至 0 项,共 0 项",
                        "sInfoFiltered": "(由 _MAX_ 项结果过滤)",
                        "sInfoPostFix": "",
                        "sSearch": "搜索:",
                        "sUrl": "",
                        "sEmptyTable": "表中数据为空",
                        "sLoadingR

以上是关于ABP之展现层(Datatables分页)的主要内容,如果未能解决你的问题,请参考以下文章

ABP

ABP官方文档翻译 1.2 N层架构

ABP总体介绍 - 层架构体系

入门ABP——多层架构体系介绍

ABP学习入门系列(菜单和分页)

ABP进阶教程6 - 功能按钮