很多时候需要这样的功能,对表格进行分页、排序和检索。这个有很多实现的方式,有
现成的表格控件、用前端的mvvm,用户控件。但很多时候看着很漂亮的东西你想进一步控制的时候却不那么如意。这里自己实现一次,功能不是高大全,但求一
个清楚明白,也欢迎园友拍砖。前端是bootstrap3+jPaginate,后台基于membership。没什么难点。
先上效果图。
分页其实就是处理好 每页项目数、总项目数、总页数、当前页。为了方便复用,就先从仓库开始说起。
一、建立仓库
1.定义Ipager接口,需要分页的模型仓库继承这个接口
namespace Protal.Model.Abstract
{ /// <summary>
/// 分页处理 /// </summary>
public interface IPager
{ /// <summary>
/// 每页项目数 /// </summary>
/// <value>The page item count.</value>
int PageItemCount { get; set; } /// <summary>
/// 总页数 /// </summary>
/// <value>The totoal page.</value>
int TotoalPage { get; } /// <summary>
/// 显示的页数 /// </summary>
/// <value>The display page.</value>
int DisplayPage { get; set; } /// <summary>
/// 满足条件的总数目 /// </summary>
int TotalItem { get; set; }
}
}
2.定义IUsersRepository,主要处理User 相关的业务逻辑。Find函数是主要的查询方法,order表示顺反排序。
public interface IUsersRepository : IPager
{ /// <summary>
/// Post list /// </summary>
/// <param name="order">Order expression</param>
/// <param name="filter">Filter expression</param>
/// <param name="skip">Records to skip</param>
/// <param name="take">Records to take</param>
/// <returns>List of users</returns>
IEnumerable<User> Find(int order=0,string filter="", int skip = 0, int take = 10); /// <summary>
/// Get single post /// </summary>
/// <param name="name">User id</param>
/// <returns>User object</returns>
User FindByName(string name); /// <summary>
/// Add new user /// </summary>
/// <param name="user">Blog user</param>
/// <returns>Saved user</returns> User Add(User user); /// <summary>
/// Update user /// </summary>
/// <param name="user">User to update</param>
/// <returns>True on success</returns>
bool Update(User user); /// <summary>
/// Save user profile /// </summary>
/// <param name="user">Blog user</param>
/// <returns>True on success</returns>
bool SaveProfile(User user); /// <summary>
/// Delete user /// </summary>
/// <param name="userName">User ID</param>
/// <returns>True on success</returns>
bool Remove(string userName);
}
二、仓库的实现和绑定
主要方法:Membership的中的User和我们自定义的不一样,所以存在一个转换
List<User> _userList = List<User>
Func<User, >
List<User> usercollection = Membership.GetAllUsers(, , (count == _usercount) = members = usercollection.Cast<MembershipUser> ( == { _userList =
IEnumerable<User> Find( order = , filter = , skip = , take = (take == ) take == .IsNullOrEmpty(filter) ? (Func<User, >) (n => n.UserName != ) : (n => users =
_totalItem == order == ? users.OrderBy(n => n.UserName).ToList() : users.OrderByDescending(n =>
(_pageItemCount == = { _pageItemCount =
page = () Math.Ceiling(() TotalItem/ page==?
(_displayPage == = { _displayPage =
(_func == = { _totalItem =
ProtalConfig.UserDisplayPage 这里是通过配置实现一个默认页数,让用户可以再webconfig中更改行列的数目。
View Code
再进行绑定:
_kernel.Bind<IUsersRepository>().To<UsersRepository>();
三、控制器部分
我们需要两个页面,一个主页面Index,一个负责局部刷新的部分视图 UserTable
下面是主要的方法,主要逻辑都在在仓库中处理了。
=
ActionResult Index( pageIndex===
ViewBag.CurrentPage =
ActionResult UserTable( pageIndex = , order = , filter = = skip = (pageIndex - ) * users =
ViewBag.TotalUser =
ViewBag.TotalPageCount =
HandlePageindex( totoalpage = (index == ) index > totoalpage ?
四、视图部分Html jquery
1.Index.cshtml
<script src="~/Scripts/form.js"></script><div class="container">
<h4 class="bottomline">管理用户</h4>
<p>
<button data-target="#adduser" id="adduserbt" data-toggle="modal" class="btn btn-info btn-hover">新增用户</button>
<button class="btn btn-danger" id="deluser">删除</button>
<span class="errorinfo"></span>
<input type="search" class="pull-right" id="usersearch" placeholder="搜索"/>
</p>
<div id="userpart">
@Html.Action("UserTable",new{pageIndex=ViewBag.CurrentPage}) </div>
<div id="userpager"></div>
<input type="hidden" id="dispalypage" value="@ViewBag.DisplayPage"/>
<input type="hidden" id="page" value="@ViewBag.CurrentPage"/>
<input type="hidden" id="currentpage" value="@ViewBag.CurrentPage"/></div><div class="modal fade adduserbox"id="adduser" tabindex="1" role="dialog" aria-hidden="true">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" >×</button>
<h4 class="modal-title">Add new User</h4>
</div>
<div class="modal-body">
@{ Html.RenderAction("Create","UserManager");
} </div>
</div></div>@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
2.UserTable.cshtml,角色部分还未处理,这个表格更新之后,也会更新满足条件的用户数和新的总页数,触发Jpaginate重新分页一次。
@model IEnumerable<Protal.Model.Data.User.User>
<table id="usertable" class="table table-striped table-condensed table-hover table-bordered">
<tr>
<th><input type="checkbox" id="allcheck" /><label for="allcheck">全选</label></th>
<th><a href="#" id="usersort" data-order="0" class="glyphicon-sort">名称</a></th>
<th>角色</th>
<th>E-mail</th>
</tr>
<tbody>
@foreach (var item in Model) { <tr>
<td> <input type="checkbox" data-id="@item.UserName" /></td>
<td> <a>@item.UserName</a> </td>
<td> @Html.Raw(item.Role) </td>
<td> @item.Email</td>
</tr>
}</tbody>
<tfoot>
<tr>
<td colspan="4">
<span>@Html.Raw("共"+ViewBag.TotalUser+"人")</span> @*<span>@ViewBag.TotalPageCount</span>*@ </td>
</tr>
</tfoot>
</table>
<input type="hidden" id="totoalpage" value="@ViewBag.TotalPageCount"/>
3.脚本
其中用到的像checkall,infoShow 都是自己扩展的一些简单的方法,用于全选和提示。
View Code
到这里就是全部的代码,供大家和自己参考。
再给大家看两个效果图,一个是kendoui的grid,一个是Angular做的分页。后面有机会给大家介绍。
Kendo- Grid
Kendo和MVC框架融合度比较高,它的核心代码如下:
View Code
AngularJs 核心还是调用封装好的API函数,相当于上面的仓库中的方法,然后通过模型绑定。
总结一下:自己实现代码量比较多,功能不全,有重复造轮子的感觉,但可以较好的控制,基本够用;kendo的方式感觉高大全,用熟了开发速度快。
就是多一些引用,且需要担心kendoui和其他的ui框架会有冲突。前端MVVM的方式我了解还不够深,感觉前端脚本的代码量也蛮多,效果不错。但生成
的html代码很少。上面这个表格。chrome F12或者右键查看源码都是下面这样子的:
主要的就一个div
<div data-ng-app="blogAdmin" data-ng-view="" id="ng-view"></div>
自我保护倒是蛮好,也就是SEO可能有问题。应该还有更好的方式,猿友们指点指点。
View Code
希望对你有帮助,Tks!
PS:这个东西没什么难度,逻辑都在仓库中,要源码的同学我后续分离出来了再贴出来。当然这个又很多方式,我也不是要秀什么框架,但我目前项目的需求是要这么分开的。一个控制器是可用解决所有问题,但我其他模型也要分页又要便于测试难道我都写在控制器中吗?