英文:
Pagination Partial wanting to use with multiple controllers, models and views
问题
_pagination.cshtml
@model CTA_Client.Models.BasePageableModel
@if (Model.PageSize > 0 )
{
<div class="center-block text-center">
<ul class="pagination mb-lg-0 mb-5">
<li class="page-item page-prev @(Model.HasPreviousPage == false ? "disabled" : "")" asp-route-PageNumber="@(Model.PageNumber - 1)">
<a class="page-link" tabindex="-1" asp-controller="Blog" asp-action="List" asp-route-PageNumber="@(Model.PageNumber - 1)">Prev</a>
</li>
@for (int i = 1; i <= Model.PageSize; i++)
{
<li class="page-item @(@i == @Model.PageNumber ? "active" : "")">
<a class="page-link" asp-controller="Blog" asp-action="List" asp-route-PageNumber="@i">@i</a>
</li>
}
<li class="page-item page-next">
<a class="page-link" asp-controller="Blog" asp-action="List" asp-route-PageNumber="@(Model.PageNumber + 1)">Next</a>
</li>
</ul>
</div>
}
Blog.cshtml
...
</div>
@Html.Partial("~/Views/Shared/_pagination.cshtml", Model.PagingFilteringContext)
</div>
<!--/lists-->
BlogPagingFilteringModel.cs
public class BlogPostListModel : BaseEntityModel
{
public BlogPostListModel()
{
PagingFilteringContext = new BlogPagingFilteringModel();
BlogPosts = new List<BlogPostModel>();
}
public BlogPagingFilteringModel PagingFilteringContext { get; set; }
public IList<BlogPostModel> BlogPosts { get; set; }
}
You can see where I get the PagingFilteringContext
that I pass from the parent View to the partial, this gives me the current paging values needed. I just need to be able to make the <a></a>
tags dynamic in a way that I can use this in multiple views.
英文:
I have created a partial for my pagination and want to use it for multiple pages like for an example a site that has a blog section and an e-comm section. I can get this to work for the most part the only thing that I can't figure out is having this work for multiple views that have different ViewModels and Controllers. Currently I have that hardcoded with the controllers and actions.
_pagination.cshtml
@model CTA_Client.Models.BasePageableModel
@if (Model.PageSize > 0 )
{
<div class="center-block text-center">
<ul class="pagination mb-lg-0 mb-5">
<li class="page-item page-prev @(Model.HasPreviousPage == false ? "disabled" : "")" asp-route-PageNumber="@(Model.PageNumber - 1)">
<a class="page-link" tabindex="-1" asp-controller="Blog" asp-action="List" asp-route-PageNumber="@(Model.PageNumber - 1)">Prev</a>
</li>
@for (int i = 1; i <= Model.PageSize; i++)
{
<li class="page-item @(@i == @Model.PageNumber ? "active" : "")">
<a class="page-link" asp-controller="Blog" asp-action="List" asp-route-PageNumber="@i">@i</a>
</li>
}
<li class="page-item page-next">
<a class="page-link" asp-controller="Blog" asp-action="List" asp-route-PageNumber="@(Model.PageNumber + 1)">Next</a>
</li>
</ul>
</div>
}
Blog.cshtml
...
</div>
@Html.Partial("~/Views/Shared/_pagination.cshtml", Model.PagingFilteringContext)
</div>
<!--/lists-->
I created a <ModelNameHere>ListModel
for each controller/Model that I will be using in the parent ViewModel. Here is the the BlogListViewModel
one.
BlogPagingFilteringModel.cs
public class BlogPostListModel : BaseEntityModel
{
public BlogPostListModel()
{
PagingFilteringContext = new BlogPagingFilteringModel();
BlogPosts = new List<BlogPostModel>();
}
public BlogPagingFilteringModel PagingFilteringContext { get; set; }
public IList<BlogPostModel> BlogPosts { get; set; }
}
You can see where I get the PagingFilteringContext
that I pass from the parent View to the partial, this gives me the current paging values needed. I just need to be able to make the <a></a>
tags dynamic in a way that I can use this in multiple views.
答案1
得分: 2
如果您在同一页上操作,例如从 /Home/Blog
到 /Home/Blog
,您可以使用 ViewContext.RouteData.Values
来获取相应的控制器和操作:
<a class="page-link" asp-controller="@ViewContext.RouteData.Values["Controller"]" asp-action="@ViewContext.RouteData.Values["Action"]" asp-route-PageNumber="@i">@i</a>
HTML 显示为:
如果您调用的控制器和操作不是当前执行的,您可以在一个模型中包含 PageNumber, Controller, Action,
等属性,并将它们传递给局部视图。
例如:
模型:
public class BlogPostModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
public class BaseModel
{
public int? PageNumber { get; set; }
public int PageCount { get; set; }
public bool HasPreviousPage { get; set; }
public bool HasNextPage { get; set; }
public string Controller { get; set; }
public string Action { get; set; }
}
控制器:
public async Task<IActionResult> Blog(int? pageNumber = 1)
{
var blogs = _context.BlogPostModel;
int pageSize = 3;
var BaseModel = new BaseModel()
{
PageNumber = pageNumber,
PageCount = (int)Math.Ceiling(blogs.Count() / (double)pageSize),
HasPreviousPage = pageNumber > 1 ? true : false,
HasNextPage = pageNumber < (int)Math.Ceiling(blogs.Count() / (double)pageSize) ? true : false,
Controller = "Home",
Action = "Blog"
};
ViewData["BaseModel"] = BaseModel;
return View(await PaginatedList<BlogPostModel>.CreateAsync(blogs.AsNoTracking(), pageNumber ?? 1, pageSize));
}
PaginatedList(参考 此文档):
public class PaginatedList<T> : List<T>
{
public int PageIndex { get; private set; }
public int TotalPages { get; private set; }
public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
{
PageIndex = pageIndex;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);
this.AddRange(items);
}
public bool HasPreviousPage => PageIndex > 1;
public bool HasNextPage => PageIndex < TotalPages;
public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize)
{
var count = await source.CountAsync();
var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
return new PaginatedList<T>(items, count, pageIndex, pageSize);
}
}
Blog.cshtml:
@model PaginatedList<TestApp.Models.BlogPostModel>
//...
<div>
@Html.Partial("~/Views/Shared/_pagination.cshtml", ViewData["BaseModel"])
</div>
_pagination.cshtml:
@model TestApp.Models.BaseModel
@if (Model.PageCount > 0)
{
<div class="center-block text-center">
<ul class="pagination mb-lg-0 mb-5">
<li class="page-item page-prev @(Model.HasPreviousPage == false ? "disabled" : "")" asp-route-PageNumber="@(Model.PageNumber - 1)">
<a class="page-link" tabindex="-1" asp-controller="@Model.Controller" asp-action="@Model.Action" asp-route-PageNumber="@(Model.PageNumber - 1)">Prev</a>
</li>
@for (int i = 1; i <= Model.PageCount; i++)
{
<li class="page-item @(i == Model.PageNumber ? "active" : "")">
<a class="page-link" asp-controller="@Model.Controller" asp-action="@Model.Action" asp-route-PageNumber="@i">@i</a>
</li>
}
<li class="page-item page-next @(Model.HasNextPage == false ? "disabled" : "")">
<a class="page-link" asp-controller="@Model.Controller" asp-action="@Model.Action" asp-route-PageNumber="@(Model.PageNumber + 1)">Next</a>
</li>
</ul>
</div>
}
英文:
If you are operating in the same page, for example, /Home/Blog
to /Home/Blog
, you can use ViewContext.RouteData.Values
to get the corresponding controller and action:
<a class="page-link" asp-controller="@ViewContext.RouteData.Values["Controller"]" asp-action="@ViewContext.RouteData.Values["Action"]" asp-route-PageNumber="@i">@i</a>
Html is displayed as
If you call a controller and action that is not currently executing, you can include PageNumber, Controler, Action, etc.
attributes in a Model and pass them to the partial view.
For example:
Models:
public class BlogPostModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
public class BaseModel
{
public int? PageNumber { get; set; }
public int PageCount { get; set; }
public bool HasPreviousPage { get; set; }
public bool HasNextPage { get; set; }
public string Controller { get; set; }
public string Action { get; set; }
}
Controller:
public async Task<IActionResult> Blog(int? pageNumber = 1)
{
var blogs = _context.BlogPostModel;
int pageSize = 3;
var BaseModel = new BaseModel()
{
PageNumber = pageNumber,
PageCount = (int)Math.Ceiling(blogs.Count() / (double)pageSize),
HasPreviousPage = pageNumber > 1 ? true : false,
HasNextPage = pageNumber < (int)Math.Ceiling(blogs.Count() / (double)pageSize) ? true : false,
Controller = "Home",
Action = "Blog"
};
ViewData["BaseModel"] = BaseModel;
return View(await PaginatedList<BlogPostModel>.CreateAsync(blogs.AsNoTracking(), pageNumber ?? 1, pageSize));
}
PaginatedList(refer to this document):
public class PaginatedList<T> : List<T>
{
public int PageIndex { get; private set; }
public int TotalPages { get; private set; }
public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
{
PageIndex = pageIndex;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);
this.AddRange(items);
}
public bool HasPreviousPage => PageIndex > 1;
public bool HasNextPage => PageIndex < TotalPages;
public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize)
{
var count = await source.CountAsync();
var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
return new PaginatedList<T>(items, count, pageIndex, pageSize);
}
}
Blog.cshtml:
@model PaginatedList<TestApp.Models.BlogPostModel>
//...
<div>
@Html.Partial("~/Views/Shared/_pagination.cshtml", ViewData["BaseModel"])
</div>
_pagination.cshtml:
@model TestApp.Models.BaseModel
@if (Model.PageCount > 0)
{
<div class="center-block text-center">
<ul class="pagination mb-lg-0 mb-5">
<li class="page-item page-prev @(Model.HasPreviousPage == false ? "disabled" : "")" asp-route-PageNumber="@(Model.PageNumber - 1)">
<a class="page-link" tabindex="-1" asp-controller="@Model.Controller" asp-action="@Model.Action" asp-route-PageNumber="@(Model.PageNumber - 1)">Prev</a>
</li>
@for (int i = 1; i <= Model.PageCount; i++)
{
<li class="page-item @(@i == @Model.PageNumber ? "active" : "")">
<a class="page-link" asp-controller="@Model.Controller" asp-action="@Model.Action" asp-route-PageNumber="@i">@i</a>
</li>
}
<li class="page-item page-next @(Model.HasNextPage == false ? "disabled" : "")">
<a class="page-link" asp-controller="@Model.Controller" asp-action="@Model.Action" asp-route-PageNumber="@(Model.PageNumber + 1)">Next</a>
</li>
</ul>
</div>
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论