Pagination Partial 想要与多个控制器、模型和视图一起使用

huangapple go评论67阅读模式
英文:

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 &gt; 0 )
{
	&lt;div class=&quot;center-block text-center&quot;&gt;
		&lt;ul class=&quot;pagination mb-lg-0 mb-5&quot;&gt;
			&lt;li class=&quot;page-item page-prev @(Model.HasPreviousPage == false ? &quot;disabled&quot; : &quot;&quot;)&quot; asp-route-PageNumber=&quot;@(Model.PageNumber - 1)&quot;&gt;
				&lt;a class=&quot;page-link&quot; tabindex=&quot;-1&quot; asp-controller=&quot;Blog&quot; asp-action=&quot;List&quot; asp-route-PageNumber=&quot;@(Model.PageNumber - 1)&quot;&gt;Prev&lt;/a&gt;
			&lt;/li&gt;
			@for (int i = 1; i &lt;= Model.PageSize; i++)
			{					
				&lt;li class=&quot;page-item @(@i == @Model.PageNumber ? &quot;active&quot; : &quot;&quot;)&quot;&gt;
					&lt;a class=&quot;page-link&quot; asp-controller=&quot;Blog&quot; asp-action=&quot;List&quot; asp-route-PageNumber=&quot;@i&quot;&gt;@i&lt;/a&gt;
				&lt;/li&gt;
			}		
			&lt;li class=&quot;page-item page-next&quot;&gt;
				&lt;a class=&quot;page-link&quot; asp-controller=&quot;Blog&quot; asp-action=&quot;List&quot; asp-route-PageNumber=&quot;@(Model.PageNumber + 1)&quot;&gt;Next&lt;/a&gt;
			&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/div&gt;
}

Blog.cshtml

			... 
            &lt;/div&gt;
			@Html.Partial(&quot;~/Views/Shared/_pagination.cshtml&quot;, Model.PagingFilteringContext)
		&lt;/div&gt;
		&lt;!--/lists--&gt;

I created a &lt;ModelNameHere&gt;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&lt;BlogPostModel&gt;(); 
	}

	public BlogPagingFilteringModel PagingFilteringContext { get; set; }
	public IList&lt;BlogPostModel&gt; 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 &lt;a&gt;&lt;/a&gt; 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 显示为:

Pagination Partial 想要与多个控制器、模型和视图一起使用

如果您调用的控制器和操作不是当前执行的,您可以在一个模型中包含 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:

&lt;a class=&quot;page-link&quot; asp-controller=&quot;@ViewContext.RouteData.Values[&quot;Controller&quot;]&quot; asp-action=&quot;@ViewContext.RouteData.Values[&quot;Action&quot;]&quot; asp-route-PageNumber=&quot;@i&quot;&gt;@i&lt;/a&gt;

Html is displayed as

Pagination Partial 想要与多个控制器、模型和视图一起使用

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&lt;IActionResult&gt; 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 &gt; 1 ? true : false,
            HasNextPage = pageNumber &lt; (int)Math.Ceiling(blogs.Count() / (double)pageSize) ? true : false,
            Controller = &quot;Home&quot;,
            Action = &quot;Blog&quot;
    };

    ViewData[&quot;BaseModel&quot;] = BaseModel;
    return View(await PaginatedList&lt;BlogPostModel&gt;.CreateAsync(blogs.AsNoTracking(), pageNumber ?? 1, pageSize));
}

PaginatedList(refer to this document):

public class PaginatedList&lt;T&gt; : List&lt;T&gt;
{
    public int PageIndex { get; private set; }
    public int TotalPages { get; private set; }

    public PaginatedList(List&lt;T&gt; items, int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        TotalPages = (int)Math.Ceiling(count / (double)pageSize);

        this.AddRange(items);
    }

    public bool HasPreviousPage =&gt; PageIndex &gt; 1;

    public bool HasNextPage =&gt; PageIndex &lt; TotalPages;

    public static async Task&lt;PaginatedList&lt;T&gt;&gt; CreateAsync(IQueryable&lt;T&gt; source, int pageIndex, int pageSize)
    {
        var count = await source.CountAsync();
        var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
        return new PaginatedList&lt;T&gt;(items, count, pageIndex, pageSize);
    }
}

Blog.cshtml:

@model PaginatedList&lt;TestApp.Models.BlogPostModel&gt;
//...
&lt;div&gt;
    @Html.Partial(&quot;~/Views/Shared/_pagination.cshtml&quot;, ViewData[&quot;BaseModel&quot;])
&lt;/div&gt;

_pagination.cshtml:

@model TestApp.Models.BaseModel

@if (Model.PageCount &gt; 0)
{
    &lt;div class=&quot;center-block text-center&quot;&gt;
        &lt;ul class=&quot;pagination mb-lg-0 mb-5&quot;&gt;
            &lt;li class=&quot;page-item page-prev @(Model.HasPreviousPage == false ? &quot;disabled&quot; : &quot;&quot;)&quot; asp-route-PageNumber=&quot;@(Model.PageNumber - 1)&quot;&gt;
                &lt;a class=&quot;page-link&quot; tabindex=&quot;-1&quot; asp-controller=&quot;@Model.Controller&quot; asp-action=&quot;@Model.Action&quot; asp-route-PageNumber=&quot;@(Model.PageNumber - 1)&quot;&gt;Prev&lt;/a&gt;
            &lt;/li&gt;
            @for (int i = 1; i &lt;= Model.PageCount; i++)
            {
                &lt;li class=&quot;page-item @(@i == @Model.PageNumber ? &quot;active&quot; : &quot;&quot;)&quot;&gt;
                    &lt;a class=&quot;page-link&quot; asp-controller=&quot;@Model.Controller&quot; asp-action=&quot;@Model.Action&quot; asp-route-PageNumber=&quot;@i&quot;&gt;@i&lt;/a&gt;
                &lt;/li&gt;
            }
            &lt;li class=&quot;page-item page-next @(Model.HasNextPage == false ? &quot;disabled&quot; : &quot;&quot;)&quot;&gt;
                &lt;a class=&quot;page-link&quot; asp-controller=&quot;@Model.Controller&quot; asp-action=&quot;@Model.Action&quot; asp-route-PageNumber=&quot;@(Model.PageNumber + 1)&quot;&gt;Next&lt;/a&gt;
            &lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;
}

huangapple
  • 本文由 发表于 2023年6月26日 02:50:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76551963.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定