PageFilter的定义
在 View 中:
DisplayTemplate的定义 :
public abstract class FilterBase
{
public string Prefix { get; set; }
protected abstract void Internal_ApplyFilter<TDefaultDocument>(MongoCursor<TDefaultDocument> cursor);
private readonly IList<FilterBase> _childFilters = new List<FilterBase>();
public T WithFilter<T>(T filter) where T : FilterBase
{
_childFilters.Add(filter);
return filter;
}
public void AddFilter<T>(T filter) where T : FilterBase
{
_childFilters.Add(filter);
}
protected FilterBase(string prefix)
{
Prefix = prefix;
}
protected FilterBase(FilterBase relatedFilter)
{
Prefix = relatedFilter.Prefix;
relatedFilter.AddFilter(this);
}
public MongoCursor<TDefaultDocument> ApplyFilter<TDefaultDocument>(MongoCursor<TDefaultDocument> cursor)
{
Internal_ApplyFilter(cursor);
foreach (var childFilter in _childFilters)
{
childFilter.ApplyFilter<TDefaultDocument>(cursor);
}
return cursor;
}
public class PagingFilter : FilterBase
{
private int _itemsPerPage = 50;
private int _currentPage = 1;
private int _pagesPerPaginate = 9;
public bool IsHttpPost { get; private set; }
public PagingFilter(FilterBase filterBase, IBaseFilterContext context)
: base(filterBase)
{
IsNeedPaging = true;
UpdateContext(filterBase.Prefix, context);
}
private PagingFilter(string prefix)
: base(prefix)
{
IsNeedPaging = true;
}
public PagingFilter(string prefix, IBaseFilterContext context, int itemsPerPage = 50)
: this(prefix)
{
UpdateContext(prefix, context, itemsPerPage);
}
private void UpdateContext(string prefix, IBaseFilterContext context, int itemsPerPage = 50)
{
ItemsPerPage = itemsPerPage;
if (context == null)
{
throw new ArgumentNullException("context");
}
try
{
var currentPage = Convert.ToInt32(context.Parameter(PrivateCurrentPageParamName(prefix)));
if (currentPage > 0)
{
_currentPage = currentPage;
}
}
catch (Exception)
{
}
_itemsPerPage = itemsPerPage;
try
{
itemsPerPage = Convert.ToInt32(context.Parameter(PrivateItemsPerPageParamName(prefix)));
if (itemsPerPage > 0)
{
_itemsPerPage = ItemsPerPage;
}
}
catch (Exception)
{
}
}
public PagingFilter(int pageNumber, int itemsPerPage, string prefix)
: this(prefix)
{
_currentPage = pageNumber;
ItemsPerPage = itemsPerPage;
}
private string PrivateItemsPerPageParamName(string prefix)
{
return string.Format("{0}ip", prefix);
}
public string ItemsPerPageParamName
{
get { return PrivateItemsPerPageParamName(Prefix); }
}
private string PrivateCurrentPageParamName(string prefix)
{
return string.Format("{0}cp", prefix);
}
public string CurrentPageParamName
{
get { return PrivateCurrentPageParamName(Prefix); }
}
public int Skip
{
get
{
return (CurrentPage - 1) * _itemsPerPage;
}
}
public int Take
{
get
{
return _itemsPerPage;
}
set
{
_itemsPerPage = value;
}
}
public bool IsNeedPaging { get; set; }
public long TotalCount { get; set; }
public int CurrentPage
{
get
{
if (_currentPage <= 0)
{
return 1;
}
return _currentPage;
}
}
public bool IsCurrentPage(long page)
{
return CurrentPage == page;
}
public long PageEnd
{
get
{
var pageEnd = CurrentPage * ItemsPerPage;
if (pageEnd > TotalCount)
{
return TotalCount;
}
return pageEnd;
}
}
public int ItemsPerPage
{
get
{
return _itemsPerPage;
}
set
{
_itemsPerPage = value;
}
}
public long TotalPagesCount
{
get
{
return TotalCount / ItemsPerPage +
((TotalCount % ItemsPerPage > 0) ? 1 : 0);
}
}
public bool FirstPage
{
get
{
return CurrentPage == 1;
}
}
public bool LastPage
{
get
{
return CurrentPage >= TotalPagesCount;
}
}
public long[] PaginationIndexes
{
get
{
var pageWindow = (_pagesPerPaginate - 1) / 2;
long start = CurrentPage - pageWindow;
if (start < 1)
{
start = 1;
}
long end = CurrentPage + pageWindow;
if (end < _pagesPerPaginate)
{
end = _pagesPerPaginate;
}
if (end > TotalPagesCount)
{
end = TotalPagesCount;
start = TotalPagesCount - _pagesPerPaginate + 1;
}
if (start < 1)
{
start = 1;
}
var retVal = new long[end - start + 1];
for (int i = 0; i < retVal.Length; i++)
{
retVal[i] = start++;
}
return retVal;
}
}
/*public MongoCursor<TDefaultDocument> ApplySort<TDefaultDocument>(MongoCursor<TDefaultDocument> cursor,
SortByBuilder sort)
{
cursor.SetSortOrder(sort);
throw new NotImplementedException();
}*/
protected override void Internal_ApplyFilter<TDefaultDocument>(MongoCursor<TDefaultDocument> cursor)
{
if (IsNeedPaging)
{
cursor.SetSkip(Skip).SetLimit(Take);
TotalCount = cursor.Count();
}
}
public PagingFilter IsHttpPosting(bool isHttpPost)
{
this.IsHttpPost = isHttpPost;
return this;
}
public PagingFilter SetCurrentPage(int page)
{
_currentPage = page;
return this;
}
}
在Mongo查询时:
pageFilter.ApplyFilter("your_mongo_collection".Find(mainQuery))
在Controller中:var pagingFilter = new PagingFilter("myd", new RequestFilterProperty(Request),20);
在 View 中:
@Html.DisplayFor(x => x.Paging)
DisplayTemplate的定义 :
@using Pearls.MVC
@model XXX.Backend.Pagination.PagingFilter
@if (Model.TotalPagesCount > 1)
{
<ul class="pagination pagination-sm">
<li class="@Model.FirstPage.AssignIfTrue("disabled")">
<a data-ishttppost="@Model.IsHttpPost" data-currentpage="@(Model.CurrentPage - 1)" href="@Url.AddParam(Model.CurrentPageParamName, Model.CurrentPage - 1)">«</a>
</li>
@foreach (var page in Model.PaginationIndexes)
{
<li class="@Model.IsCurrentPage(page).AssignIfTrue("active")">
<a data-ishttppost="@Model.IsHttpPost" data-currentpage="@page" href="@Url.AddParam(Model.CurrentPageParamName, page)">@Html.DisplayFor(x => page)</a>
</li>
}
<li class="@Model.LastPage.AssignIfTrue("disabled")">
<a data-ishttppost="@Model.IsHttpPost" data-currentpage="@(Model.CurrentPage + 1)" href="@Url.AddParam(Model.CurrentPageParamName, Model.CurrentPage + 1)">»</a>
</li>
</ul>
}