博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Asp.Net MVC 分页、检索、排序整体实现
阅读量:6231 次
发布时间:2019-06-22

本文共 13951 字,大约阅读时间需要 46 分钟。

原文:

    很多时候需要这样的功能,对表格进行分页、排序和检索。这个有很多实现的方式,有现成的表格控件、用前端的mvvm,用户控件。但很多时候看着很漂亮的东西你想进一步控制的时候却不那么如意。这里自己实现一次,功能不是高大全,但求一个清楚明白,也欢迎园友拍砖。前端是bootstrap3+jPaginate,后台基于membership。没什么难点。

    先上效果图。

    

 

    分页其实就是处理好 每页项目数、总项目数、总页数、当前页。为了方便复用,就先从仓库开始说起。

一、建立仓库

  1.定义Ipager接口,需要分页的模型仓库继承这个接口

namespace Protal.Model.Abstract{    ///     /// 分页处理    ///    public interface IPager    {        ///         /// 每页项目数        ///         /// 
The page item count.
int PageItemCount { get; set; } /// /// 总页数 /// ///
The totoal page.
int TotoalPage { get; } /// /// 显示的页数 /// ///
The display page.
int DisplayPage { get; set; } /// /// 满足条件的总数目 /// int TotalItem { get; set; } }}

2.定义IUsersRepository,主要处理User 相关的业务逻辑。Find函数是主要的查询方法,order表示顺反排序。

public interface IUsersRepository : IPager    {        ///         /// Post list        ///         /// Order expression        /// Filter expression        /// Records to skip        /// Records to take        /// 
List of users
IEnumerable
Find(int order=0,string filter="", int skip = 0, int take = 10); ///
/// Get single post /// ///
User id ///
User object
User FindByName(string name); ///
/// Add new user /// ///
Blog user ///
Saved user
User Add(User user); ///
/// Update user /// ///
User to update ///
True on success
bool Update(User user); ///
/// Save user profile /// ///
Blog user ///
True on success
bool SaveProfile(User user); ///
/// Delete user /// ///
User ID ///
True on success
bool Remove(string userName); }

 

二、仓库的实现和绑定

  主要方法:Membership的中的User和我们自定义的不一样,所以存在一个转换

public class UsersRepository : IUsersRepository   {       ///        /// The _user list       ///         private List
_userList = new List
(); ///
/// The _page item count /// private int _pageItemCount; ///
/// The _display page /// private int _displayPage; ///
/// The _usercount /// private int _usercount; ///
/// The _total item /// private int _totalItem; ///
/// 标记是否有查询条件 没有的话则返回全部数目 /// private Func
_func; ///
/// Gets or sets the users. /// ///
The users.
public List
Users { get { int count; var usercollection = Membership.GetAllUsers(0, 999, out count); if (count == _usercount) return _userList; _usercount = count; var members = usercollection.Cast
().ToList(); foreach (var membershipUser in members)//这里存在一个转换 { _userList.Add(new User { Email = membershipUser.Email, UserName = membershipUser.UserName, //roles password }); } return _userList; } set { _userList = value; } }

 

//查询 public IEnumerable
Find(int order = 0, string filter = "", int skip = 0, int take = 10) { if (take == 0) take = Users.Count; //过滤 _func = string.IsNullOrEmpty(filter) ? (Func
) (n => n.UserName != "") : (n => n.UserName.Contains(filter)); var users = Users.Where(_func).ToList(); //更新总数目 _totalItem = users.Count; users = order == 0 ? users.OrderBy(n => n.UserName).ToList() : users.OrderByDescending(n => n.UserName).ToList(); return users.Skip(skip).Take(take); } ///
/// 每页项目数 /// ///
The page item count.
public int PageItemCount { get { if (_pageItemCount == 0) { _pageItemCount = ProtalConfig.UserPageItemCount; } return _pageItemCount; } set { _pageItemCount = value; } } ///
/// 总页数 /// ///
The totoal page.
public int TotoalPage { get { var page = (int) Math.Ceiling((double) TotalItem/PageItemCount); return page==0?1:page; } } ///
/// 显示的页数 /// ///
The display page.
public int DisplayPage { get { if (_displayPage == 0) { _displayPage = ProtalConfig.UserDisplayPage; } return _displayPage; } set { _displayPage = value; } } ///
/// 满足条件的总数目 保持更新 /// ///
The total item.
public int TotalItem { get { if (_func == null) _totalItem = Users.Count; return _totalItem; } set { _totalItem = value; } }}
ProtalConfig.UserDisplayPage 这里是通过配置实现一个默认页数,让用户可以再webconfig中更改行列的数目。
public static int UserPageItemCount                {                    get                    {                        if (_userPageItemCount == 0)                        {                            _userPageItemCount = WebConfigurationManager.AppSettings["UserPageItemCount"] != null ?                                Convert.ToInt16(WebConfigurationManager.AppSettings["UserPageItemCount"]) : 5;                        }                        return _userPageItemCount;                    }                    set                    {                        _userPageItemCount = value;                    }                }
View Code

 再进行绑定:

_kernel.Bind
().To
();

 

三、控制器部分

  我们需要两个页面,一个主页面Index,一个负责局部刷新的部分视图 UserTable

 下面是主要的方法,主要逻辑都在在仓库中处理了。

[Authorize]    public class UserManagerController : Controller    {        ///         /// The _repository        ///         private readonly IUsersRepository _repository;        ///         /// Initializes a new instance of the 
class. ///
/// The i repository. public UserManagerController(IUsersRepository iRepository) { _repository = iRepository; } /// /// Indexes the specified page index. /// /// Index of the page. ///
ActionResult.
public ActionResult Index(int pageIndex=1) { ViewBag.DisplayPage = _repository.DisplayPage; pageIndex = HandlePageindex(pageIndex); //支持地址栏直接分页 ViewBag.CurrentPage = pageIndex; return View(); } /// /// Users table. 分页模块 /// /// Index of the page. /// The order. /// The filter str. ///
ActionResult.
public ActionResult UserTable(int pageIndex = 1, int order = 0, string filter = "") { pageIndex = HandlePageindex(pageIndex); var skip = (pageIndex - 1) * _repository.PageItemCount; var users = _repository.Find(order,filter, skip, _repository.PageItemCount); //总用户数 ViewBag.TotalUser = _repository.TotalItem; //总页数 ViewBag.TotalPageCount = _repository.TotoalPage; ; return PartialView(users); } /// /// 处理页数 防止过大或过小 /// /// ///
private int HandlePageindex(int index) { var totoalpage = _repository.TotoalPage; if (index == 0) return 1; return index > totoalpage ? totoalpage : index; } }

 

四、视图部分Html jquery

 1.Index.cshtml

管理用户

@Html.Action("UserTable",new{pageIndex=ViewBag.CurrentPage})
@section Scripts { @Scripts.Render("~/bundles/jqueryval")}

2.UserTable.cshtml,角色部分还未处理,这个表格更新之后,也会更新满足条件的用户数和新的总页数,触发Jpaginate重新分页一次。

@model IEnumerable
@foreach (var item in Model) {
}
名称 角色 E-mail
@item.UserName @Html.Raw(item.Role) @item.Email
@Html.Raw("共"+ViewBag.TotalUser+"人") @*@ViewBag.TotalPageCount*@

3.脚本

其中用到的像checkall,infoShow 都是自己扩展的一些简单的方法,用于全选和提示。

$(function () {        var options = {            dataType: 'json',            success: processJson        };        pageagin($("#totoalpage").val());        //分页        function pageagin(totalcount) {            $("#userpager").paginate({                count: totalcount,                start: $("#page").val(),                dispaly: $("#dispalypage").val(),                boder: false,                border_color: '#fff',//自己调整样式。                text_color: 'black',                background_color: 'none',                border_hover_color: '#ccc',                text_hover_color: '#000',                background_hover_color: '#fff',                images: false,                mouse: 'press',                onChange: function (page) { //翻页                    paging(page);                    $("#currentpage").val(page);                }            });        }        //分页更新        function paging(page) {            $.post("/Users/UserTable", { pageIndex: page, order: $("#userpart").attr("data-order"), filter: $.trim($("#usersearch").val()) }, function (data) {                $("#userpart").html(data);            });        }       //排序        $("#usersort").live("click",function () {            $("#userpart").triggerdataOrder();            paging( $("#currentpage").val());        });                //搜索        $("#usersearch").keyup(function() {            paging($("#currentpage").val());            pageagin($("#totoalpage").val());        });        //处理form        $("#userForm").submit(function () {            $(this).ajaxSubmit(options);            return false;        });        function processJson(data) {           if (data == 1) {               location.reload();           } else {               alert("添加失败");           }        }        //高亮        $("#unav li:eq(0)").addClass("active");        $("#adnav li:eq(2)").addClass("active");        //全选/全不选        $("#allcheck").checkall($("#usertable tbody input[type='checkbox']"));        //删除用户        $("#deluser").click(function () {            var checks = $("#usertable tbody input[type='checkbox']:checked");            var lens = checks.length;            if (lens == 0) {                $.infoShow("未选择删除对象",0);                return false;            }            if (confirm("确定要删除所选中用户?")) {                for (var i = 0; i < lens; i++) {                    var $chek = checks.eq(i);                    var id = $chek.attr("data-id");                    var tr = $chek.parent().parent();                    $.post("Users/DeleteUser", { id: id }, function (data) {                        if (data == 1) {                            tr.fadeOut();                            $.infoShow("删除成功", 1);                        } else {                            $.infoShow("删除失败", 0);                        }                    });                }            }             return true;        });                // 增加用户        $("#adduserbt").click(function() {            $(".modal-header").show();        });    })
View Code

到这里就是全部的代码,供大家和自己参考。

再给大家看两个效果图,一个是kendoui的grid,一个是Angular做的分页。后面有机会给大家介绍。

Kendo- Grid

 Kendo和MVC框架融合度比较高,它的核心代码如下:

@model IEnumerable
@(Html.Kendo().Grid(Model) .Name("Grid") .Columns(columns => { columns.Bound(p => p.ProductID).Groupable(false); columns.Bound(p => p.ProductName); columns.Bound(p => p.UnitPrice); columns.Bound(p => p.UnitsInStock); }) .Pageable() .Sortable() .Scrollable() .Filterable() .DataSource(dataSource => dataSource .Ajax() .ServerOperation(false) ))
View Code

AngularJs 核心还是调用封装好的API函数,相当于上面的仓库中的方法,然后通过模型绑定。

 总结一下:自己实现代码量比较多,功能不全,有重复造轮子的感觉,但可以较好的控制,基本够用;kendo的方式感觉高大全,用熟了开发速度快。就是多一些引用,且需要担心kendoui和其他的ui框架会有冲突。前端MVVM的方式我了解还不够深,感觉前端脚本的代码量也蛮多,效果不错。但生成的html代码很少。上面这个表格。chrome F12或者右键查看源码都是下面这样子的:

  主要的就一个div 

自我保护倒是蛮好,也就是SEO可能有问题。应该还有更好的方式,猿友们指点指点。

    Name of the blog (Admin)    
View Code

  希望对你有帮助,Tks!

  PS:这个东西没什么难度,逻辑都在仓库中,要源码的同学我后续分离出来了再贴出来。当然这个又很多方式,我也不是要秀什么框架,但我目前项目的需求是要这么分开的。一个控制器是可用解决所有问题,但我其他模型也要分页又要便于测试难道我都写在控制器中吗?

转载地址:http://nkqna.baihongyu.com/

你可能感兴趣的文章
ElasticSearch 2 (32) - 信息聚合系列之范围限定
查看>>
VS2010远程调试C#程序
查看>>
[MicroPython]TurniBit开发板DIY自动窗帘模拟系统
查看>>
Python3.4 12306 2015年3月验证码识别
查看>>
从Handler.post(Runnable r)再一次梳理Android的消息机制(以及handler的内存泄露)
查看>>
windows查看端口占用
查看>>
Yii用ajax实现无刷新检索更新CListView数据
查看>>
JDBC的事务
查看>>
Io流的概述
查看>>
App 卸载记录
查看>>
JavaScript变量和作用域
查看>>
开源SIP服务器加密软件NethidPro升级
查看>>
作业:实现简单的shell sed替换功能和修改haproxy配置文件
查看>>
Altium 拼板方法以及 注意的 地方
查看>>
Apache Pulsar中的地域复制,第1篇:概念和功能
查看>>
python pip install 出现 OSError: [Errno 1] Operation not permitted
查看>>
oracle12C 重做日志
查看>>
从源码分析scrollTo、scrollBy、Scroller方法的区别和作用
查看>>
ObjectOutputStream和ObjectInputStream
查看>>
nagios客户端未启动报错
查看>>