>  기사  >  백엔드 개발  >  페이징, 검색 및 정렬을 위한 Asp.Net MVC 코드 표시

페이징, 검색 및 정렬을 위한 Asp.Net MVC 코드 표시

巴扎黑
巴扎黑원래의
2017-08-16 16:14:421945검색

테이블 페이지를 매기고, 정렬하고, 검색하는 데 이러한 기능이 필요한 경우가 많습니다. 이 기사에서는 주로 Asp.Net MVC 페이징, 검색 및 정렬의 전반적인 구현을 소개합니다. 관심 있는 사용자는 자세히 알아볼 수 있습니다.

테이블 페이지를 매기고, 정렬하고, 검색하는 데 이러한 기능이 필요한 경우가 많습니다. 미리 만들어진 테이블 컨트롤, 프런트 엔드 mvvm 및 사용자 컨트롤을 포함하여 이를 구현하는 방법은 다양합니다. 그러나 당신이 매우 아름다운 것을 보고 그것을 더욱 통제하고 싶을 때 그것은 그다지 만족스럽지 않을 때가 많습니다. 여기에서 직접 구현하겠습니다. 기능이 포괄적이지는 않지만, Garden 친구들도 기여할 수 있기를 바랍니다. 프론트엔드는 bootstrap3+jPaginate이고, 백엔드는 멤버십 기반입니다. 어려운 것은 없습니다.

먼저 렌더링입니다.

페이징은 실제로 페이지당 항목 수, 총 항목 수, 총 페이지 수 및 현재 페이지를 처리하는 것입니다. 재사용을 용이하게 하기 위해 창고부터 시작해 보겠습니다.

1. Warehouse 구축

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. 주로 User 관련 비즈니스 로직을 처리하는 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

이 필요합니다. 이것이 메인 메소드이고, 메인 로직은 창고에서 처리됩니다.


  [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: &#39;json&#39;,
      success: processJson
    };
    pageagin($("#totoalpage").val());
    //分页
    function pageagin(totalcount) {
      $("#userpager").paginate({
        count: totalcount,
        start: $("#page").val(),
        dispaly: $("#dispalypage").val(),
        boder: false,
        border_color: &#39;#fff&#39;,//自己调整样式。
        text_color: &#39;black&#39;,
        background_color: &#39;none&#39;,
        border_hover_color: &#39;#ccc&#39;,
        text_hover_color: &#39;#000&#39;,
        background_hover_color: &#39;#fff&#39;,
        images: false,
        mouse: &#39;press&#39;,
        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=&#39;checkbox&#39;]"));

    //删除用户
    $("#deluser").click(function () {
      var checks = $("#usertable tbody input[type=&#39;checkbox&#39;]: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();
    });
  })

여기에 참조할 수 있는 모든 코드가 있습니다.

두 가지 렌더링을 더 보여드리겠습니다. 하나는 kendoui의 그리드이고 다른 하나는 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에 문제가 있을 수 있습니다. 더 좋은 방법이 있을 텐데 조언 좀 부탁드립니다.




  Name of the blog (Admin)
  
  
  
  
  
  
  
  






  


  
  
  

<p data-ng-app="blogAdmin" data-ng-view="" id="ng-view"></p>

PS: 이 일은 어렵지 않습니다. 소스 코드를 원하는 학생들을 위해 나중에 따로 게시하도록 하겠습니다. 물론 이를 수행하는 방법에는 여러 가지가 있으며 어떤 프레임워크도 보여주려는 것이 아니지만 현재 프로젝트의 요구 사항은 너무 분리되어 있습니다. 하나의 컨트롤러로 모든 문제를 해결할 수 있지만 다른 모델도 페이지를 매겨야 하고 테스트하기 쉬워야 합니다. 컨트롤러에 모두 작성해야 합니까?

위 내용은 페이징, 검색 및 정렬을 위한 Asp.Net MVC 코드 표시의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.