How could I improve the code for this paging control?

9

I mounted a paging control for a blog that I'm putting together, but I'm not sure if I did it the best way, I tried to copy the paging control of Stack Exchange sites. Could you guys take a look and tell me what you think?

A screenshot of how it stayed when the total of pages was equal to 10:

Theviewcodesnippetforthenavigationcontrol(IusedBootstrap):

<nav><ulclass="pagination">
        @{ 
            var totalPages = Model.TotalPostsCount / Model.PostsPerPage;

            var urlPreviousPage = Url.Action("Page", new { arg = Model.CurrentPage - 1, postsPerPage = Model.PostsPerPage });
            var urlNextPage = Url.Action("Page", new { arg = Model.CurrentPage + 1, postsPerPage = Model.PostsPerPage });
        }

        @* Navigation button << *@
        <li class="@(Model.CurrentPage == 1 ? "disabled" : null)">
            <a href="@(Model.CurrentPage != 1 ? urlPreviousPage : null)">
                <span>&laquo;</span>
            </a>
        </li>

        @* Navigation button 1 *@
        <li class="@(Model.CurrentPage == 1 ? "active" : null)"><a href="@Url.Action("Page", new { arg = 1, postsPerPage = Model.PostsPerPage })">1</a></li>

        @* Navigation buttons from 2 to 5 *@
        @if (Model.CurrentPage >= 1 && Model.CurrentPage < 5)
        {
            for (int page = 2; page <= 5; page++)
            {
                if (totalPages >= page)
                {
                    var pageUrl = Url.Action("Page", new { arg = page, postsPerPage = Model.PostsPerPage });

                    <li class="@(Model.CurrentPage == page ? "active" : null)"><a href="@pageUrl">@page</a></li>
                }
            }
        }

        <li><a>...</a></li>

        @* Middle navigation buttons *@
        @if (Model.CurrentPage >= 5 && Model.CurrentPage <= totalPages - 4)
        {
            <li><a href="@Url.Action("Page", new { arg = Model.CurrentPage - 2 })">@(Model.CurrentPage - 2)</a></li>
            <li><a href="@Url.Action("Page", new { arg = Model.CurrentPage - 1 })">@(Model.CurrentPage - 1)</a></li>
            <li class="active"><a href="@Url.Action("Page", new { arg = Model.CurrentPage })">@(Model.CurrentPage)</a></li>
            <li><a href="@Url.Action("Page", new { arg = Model.CurrentPage + 1 })">@(Model.CurrentPage + 1)</a></li>
            <li><a href="@Url.Action("Page", new { arg = Model.CurrentPage + 2 })">@(Model.CurrentPage + 2)</a></li>
            <li><a>...</a></li>
        }

        @* Navigation buttons from (totalPages - 4) to (totalPages) *@
        @if (Model.CurrentPage > totalPages - 4)
        {
            <li><a href="@Url.Action("Page", new { arg = totalPages - 4, postsPerPage = Model.PostsPerPage })">@(totalPages - 4)</a></li>
            <li class="@(Model.CurrentPage == totalPages - 3 ? "active" : null)"><a href="@Url.Action("Page", new { arg = totalPages - 3, postsPerPage = Model.PostsPerPage })">@(totalPages - 3)</a></li>
            <li class="@(Model.CurrentPage == totalPages - 2 ? "active" : null)"><a href="@Url.Action("Page", new { arg = totalPages - 2, postsPerPage = Model.PostsPerPage })">@(totalPages - 2)</a></li>
            <li class="@(Model.CurrentPage == totalPages - 1 ? "active" : null)"><a href="@Url.Action("Page", new { arg = totalPages - 1, postsPerPage = Model.PostsPerPage })">@(totalPages - 1)</a></li>
        }

        <li class="@(Model.CurrentPage == totalPages ? "active" : null)"><a href="@Url.Action("Page", new { arg = totalPages, postsPerPage = Model.PostsPerPage })">@totalPages</a></li>

        @* >> *@
        <li class="@(Model.CurrentPage == totalPages ? "disabled" : null)">
            <a href="@(Model.CurrentPage != totalPages ? urlNextPage : null)">
                <span>&raquo;</span>
            </a>
        </li>
    </ul>
</nav>

A action for you to have an idea of what is being sent to this view :

public async Task<ActionResult> Page(int arg = 1, int postsPerPage = 10)
{
    var sort = Builders<Post>.Sort.Descending(p => p.Created);

    var viewModel = new HomePageViewModel
    {
        CurrentPage = arg,
        PostsPerPage = postsPerPage,
        TotalPostsCount = await ZigBlogDb.Posts.CountAsync(_ => true),
        Posts = await ZigBlogDb.Posts.Find(_ => true).Sort(sort).Skip((arg - 1) * postsPerPage).Limit(postsPerPage).ToListAsync()
    };

    return View(viewModel);
}
    
asked by anonymous 23.11.2015 / 02:10

1 answer

4

Well, I'm sorry to tell you, but you've reinvented the wheel, yes. There is a component that does this in a more performative way . His NuGet package is here .

I saw that you are using Entity Framework. This PagedList.Mvc component does not support asynchronous paging. If you want to use asynchronous paging, also install this other NuGet package .

EDIT

You commented on using MongoDB. There is also pagination for MongoDB .

    
23.11.2015 / 03:51