Oxite分页机制的实现的一点补充
1、关键的类型
public interface IPageOfList<T> : IList<T>
{
int PageIndex { get; }
int PageSize { get; }
int TotalPageCount { get; }
int TotalItemCount { get; }
}
public class PageOfList<T> : List<T>, IPageOfList<T>
{
public PageOfList(IEnumerable<T> items, int pageIndex, int pageSize, int totalItemCount)
{
AddRange(items);
PageIndex = pageIndex;
PageSize = pageSize;
TotalItemCount = totalItemCount;
TotalPageCount = (int)Math.Ceiling(totalItemCount / (double)pageSize);
}
#region IPageOfList<T> Members
public int PageIndex { get; set; }
public int PageSize { get; set; }
public int TotalItemCount { get; set; }
public int TotalPageCount { get; private set; }
#endregion
}
public static class IQueryableExtensions
{
public static PageOfList<T> GetPage<T>(this IQueryable<T> query, int pageIndex, int pageSize)
{
return new PageOfList<T>(query.Skip(pageIndex * pageSize).Take(pageSize), pageIndex, pageSize, query.Count());
}
}
2、解析开始
在观擦了以上接口的定义以后,可以知道只要是实现了IPageOfList接口的类型就能进行分页操作。我们在看PostService.GetPosts的方法的时候,应该注意到这个方法是这么定义的。
return sinceDate.HasValue ? repository.GetPosts(sinceDate.Value.ToUniversalTime()).GetPage(pageIndex, pageSize) : repository.GetPosts(false).GetPage(pageIndex, pageSize);
你可能很奇怪,repository.GetPosts()返回的是一个IQueryable<T>接口,难道两个接口可以互相转换?仅仅因为IList<T>实现了IEnumerable<T>接口而IQueryable<T>也实现了这个接口?其实不是的,如果注意看,你会发现在代码的后面那个GetPage()方法。这个是一个IQueryable<T>的拓展方法,这样,其实就是返回了一个PageOfList<T>对象。
然后,在Views\Post\List.aspx下就可以用<%=Html.PageState((IPageOfList<Post>)Model.List, (k, v) => Model.Localize(k, v))%>这个HtmlHelper的拓展方法来实现和分页相关的操作了。