Asp.Net MVC如何实现分页、检索、排序整体的功能
创始人
2024-11-28 04:43:28
0次

先上效果图。

Asp.Net MVC如何实现分页、检索、排序整体的功能

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

一、建立仓库

  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;
          }
        }

再进行绑定:

 _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})   
  
        
               ×        Add new User     
           @{         Html.RenderAction("Create","UserManager");       }     
  
@section Scripts {   @Scripts.Render("~/bundles/jqueryval") }

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

@model IEnumerable
 
    
      全选
      名称
      角色
      E-mail
    
    
      @foreach (var item in Model) {
        
           
           @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();
    });
  })

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

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

Kendo- Grid

Asp.Net MVC如何实现分页、检索、排序整体的功能

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)    
   )
)

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

Asp.Net MVC如何实现分页、检索、排序整体的功能

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

主要的就一个div 

 

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



  Name of the blog (Admin)
  
  
  
  
  
  
  
  






  
    if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
      var msViewportStyle = document.createElement("style");
      var mq = "@-ms-viewport{width:auto!important}";
      msViewportStyle.appendChild(document.createTextNode(mq));
      document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
    }
  


  
    var SiteVars = {
      ApplicationRelativeWebRoot: '/',
      RelativeWebRoot: '/',
      BlogInstanceId: '96d5b379-7e1d-4dac-a6ba-1e50db561b04',
      UserName: 'admin',
      UserRights: ['ViewDetailedErrorMessages', 'AccessAdminPages', 'AccessAdminSettingsPages', 'ManageWidgets', 'ViewPublicComments', 'ViewUnmoderatedComments', 'CreateComments', 'ModerateComments', 'ViewPublicPosts', 'ViewUnpublishedPosts', 'CreateNewPosts', 'EditOwnPosts', 'EditOtherUsersPosts', 'DeleteOwnPosts', 'DeleteOtherUsersPosts', 'PublishOwnPosts', 'PublishOtherUsersPosts', 'ViewPublicPages', 'ViewUnpublishedPages', 'CreateNewPages', 'EditOwnPages', 'ViewRatingsOnPosts', 'SubmitRatingsOnPosts', 'ViewRoles', 'CreateNewRoles', 'EditRoles', 'DeleteRoles', 'EditOwnRoles', 'EditOtherUsersRoles', 'CreateNewUsers', 'DeleteUserSelf', 'DeleteUsersOtherThanSelf', 'EditOwnUser', 'EditOtherUsers'],
      AbsoluteWebRoot: 'http://localhost:53265/',
      Version: 'BlogEngine.NET ' + '2.9.1.0',
      IsPrimary: 'True',
      IsAdmin: 'True',
      AppRoot: function (url) { window.location = '/' + url; return false; },
      BlogRoot: function (url) { window.location = '/' + url; }
    };
  
  
  
    
  
     

上一篇:asp.net Mvc4如何使用ajax结合分页插件实现无刷新分页

下一篇:如何解决ASP.NET MVC下基于异常处理的问题

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...