テーブルのページネーション、ソート、取得には多くの場合、このような関数が必要です。この記事では主に、Asp.Net MVC のページング、取得、並べ替えの全体的な実装について紹介します。興味がある方は詳細をご覧ください。
多くの場合、テーブルのページネーション、並べ替え、取得のためにこのような関数が必要になります。これを実装するには、既製のテーブル コントロール、フロントエンド mvvm、ユーザー コントロールなど、さまざまな方法があります。しかし、非常に美しいものを見て、それをさらにコントロールしたいと思っても、それほど満足のいくものではないことがよくあります。ここでは私自身が実装します。機能は包括的ではありませんが、Garden の友人にも協力していただけると幸いです。フロントエンドは bootstrap3+jPaginate で、バックエンドはメンバーシップに基づいています。何も難しいことはありません。
まず、レンダリングです。
ページングは実際には、ページごとのアイテム数、アイテムの合計数、ページの合計数、および現在のページを処理します。再利用を促進するには、倉庫から始めましょう。
1. ウェアハウスを確立します
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 を定義します。 Find 機能は主なクエリ方法であり、順序とは順方向および逆方向の並べ替えを意味します。
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); }
2. ウェアハウスの実装とバインディング
メインメソッド: Membership のユーザーはカスタマイズされたユーザーとは異なるため、変換が発生します
public class UsersRepository : IUsersRepository { /// <summary> /// The _user list /// </summary> private List<User> _userList = new List<User>(); /// <summary> /// The _page item count /// </summary> private int _pageItemCount; /// <summary> /// The _display page /// </summary> private int _displayPage; /// <summary> /// The _usercount /// </summary> private int _usercount; /// <summary> /// The _total item /// </summary> private int _totalItem; /// <summary> /// 标记是否有查询条件 没有的话则返回全部数目 /// </summary> private Func<User, bool> _func; /// <summary> /// Gets or sets the users. /// </summary> /// <value>The users.</value> public List<User> Users { get { int count; var usercollection = Membership.GetAllUsers(0, 999, out count); if (count == _usercount) return _userList; _usercount = count; var members = usercollection.Cast<MembershipUser>().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<User> Find(int order = 0, string filter = "", int skip = 0, int take = 10) { if (take == 0) take = Users.Count; //过滤 _func = string.IsNullOrEmpty(filter) ? (Func<User, bool>) (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); } /// <summary> /// 每页项目数 /// </summary> /// <value>The page item count.</value> public int PageItemCount { get { if (_pageItemCount == 0) { _pageItemCount = ProtalConfig.UserPageItemCount; } return _pageItemCount; } set { _pageItemCount = value; } } /// <summary> /// 总页数 /// </summary> /// <value>The totoal page.</value> public int TotoalPage { get { var page = (int) Math.Ceiling((double) TotalItem/PageItemCount); return page==0?1:page; } } /// <summary> /// 显示的页数 /// </summary> /// <value>The display page.</value> public int DisplayPage { get { if (_displayPage == 0) { _displayPage = ProtalConfig.UserDisplayPage; } return _displayPage; } set { _displayPage = value; } } /// <summary> /// 满足条件的总数目 保持更新 /// </summary> /// <value>The total item.</value> 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; } }
次にバインドします:
_kernel.Bind<IUsersRepository>().To<UsersRepository>();
3. コントローラー部分
メインページの Index と部分ビューの UserTable
の 2 つのページが必要です。これがメインのメソッドであり、メインロジックはウェアハウスで処理されます。
[Authorize] public class UserManagerController : Controller { /// <summary> /// The _repository /// </summary> private readonly IUsersRepository _repository; /// <summary> /// Initializes a new instance of the <see cref="UserManagerController"/> class. /// </summary> /// <param name="iRepository">The i repository.</param> public UserManagerController(IUsersRepository iRepository) { _repository = iRepository; } /// <summary> /// Indexes the specified page index. /// </summary> /// <param name="pageIndex">Index of the page.</param> /// <returns>ActionResult.</returns> public ActionResult Index(int pageIndex=1) { ViewBag.DisplayPage = _repository.DisplayPage; pageIndex = HandlePageindex(pageIndex); //支持地址栏直接分页 ViewBag.CurrentPage = pageIndex; return View(); } /// <summary> /// Users table. 分页模块 /// </summary> /// <param name="pageIndex">Index of the page.</param> /// <param name="order">The order.</param> /// <param name="filter">The filter str.</param> /// <returns>ActionResult.</returns> 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); } /// <summary> /// 处理页数 防止过大或过小 /// </summary> /// <param name="index"></param> /// <returns></returns> private int HandlePageindex(int index) { var totoalpage = _repository.TotoalPage; if (index == 0) return 1; return index > totoalpage ? totoalpage : index; } }
4. ビュー部分 Html jquery
1.Index.cshtml
<script src="~/Scripts/form.js"></script> <p 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> <p id="userpart"> @Html.Action("UserTable",new{pageIndex=ViewBag.CurrentPage}) </p> <p id="userpager"></p> <input type="hidden" id="dispalypage" value="@ViewBag.DisplayPage"/> <input type="hidden" id="page" value="@ViewBag.CurrentPage"/> <input type="hidden" id="currentpage" value="@ViewBag.CurrentPage"/> </p> <p class="modal fade adduserbox"id="adduser" tabindex="1" role="dialog" aria-hidden="true"> <p class="modal-content"> <p class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true" >×</button> <h4 class="modal-title">Add new User</h4> </p> <p class="modal-body"> @{ Html.RenderAction("Create","UserManager"); } </p> </p> </p> @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 などのスクリプト
は、すべてを選択してプロンプトを表示するために独自に拡張されたいくつかの単純なメソッドです。
$(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(); }); })
参考までに、すべてのコードをここに示します。
あと 2 つのレンダリングをお見せします。1 つは kendoui のグリッドで、もう 1 つは Angular によって作成されたページングです。機会があればまた紹介させていただきます。
Kendo- Grid
Kendo は MVC フレームワークと高度に統合されており、そのコア コードは次のとおりです。
@model IEnumerable<Kendo.Mvc.Examples.Models.ProductViewModel> @(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) ) )
AngularJs コアは引き続き、カプセル化された API 関数を呼び出します。これは、次に、モデルバインディングを経由します。
要約すると、私が実装したコードの量は比較的多く、機能は完全ではなく、車輪の再発明のような感じですが、より適切に制御でき、基本的に剣道のメソッドは高度で完成されていると感じます。 , 慣れてしまえば開発スピードも早いです。参照が増えるだけで、Kendoui と他の UI フレームワーク間の競合を心配する必要があります。フロントエンドの MVVM 方式についてはよくわかりませんが、フロントエンド スクリプトのコード量はかなり多く、効果は十分にあると感じています。ただし、生成される HTML コードは非常に小さいです。上の表。 Chrome F12 または右クリックしてソース コードを表示すると、次のようになります:
主なものは単なる p です
<p data-ng-app="blogAdmin" data-ng-view="" id="ng-view"></p>
自分自身を守るのは良いことです。つまり、SEO に問題がある可能性があります。もっと良い方法があるはずですので、アドバイスをお願いします。
PS: これは難しいことではありません。ソースコードが必要な学生のために、後で分割して投稿します。もちろん、これを行う方法はたくさんありますし、フレームワークを誇示するつもりはありませんが、現在のプロジェクトのニーズは非常に分かれています。 1 つのコントローラーですべての問題を解決できますが、他のモデルもページ分割してテストしやすくする必要があります。それらをすべてコントローラーに記述する必要がありますか?
以上がページング、取得、並べ替えのための Asp.Net MVC コード表示の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。