How to load first x items and give user the option to load more in MVC.NET

不想你离开。 提交于 2019-11-28 11:39:49

This is similar to paging except that you retain the previous fetches. Your view model needs to have one more property of a helper class:

public class PagingInfo
{
    public int TotalItems { get; set; }
    public int ItemsPerPage { get; set; }
    public int CurrentPage { get; set; }
    public int TotalPages
    {
        get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); }
    }
}

public class QuestionsListViewModel
{
    public IEnumerable<Question> Questions { get; set; }
    public PagingInfo PagingInfo { get; set; }
}

And when you render the QuestionsListViewModel, use a similar Razor Code:

@foreach (var p in Model.Questions)
{
    // render Questions
}

@Html.ActionLink("Load next 25 items", "Questions", "Controller", new { page = Model.PagingInfo.CurrentPage + 1 }))

Questions is your Controller Action as follows:

    public ViewResult Questions(int page = 1)
    {
        QuestionsListViewModelmodel = new QuestionsListViewModel
        {
            // we need to get all items till now to render again 
            Questions = repository.Questions
                                  .Take(page * PageSize),
            PagingInfo = new PagingInfo
            {
                CurrentPage = page,
                ItemsPerPage = 25,
                TotalItems = repository.Questions.Count()
            }
        };

        return View(model);
    }

You can actually use the TotalItems property to give a smart message for loading next items.

If you don't want to go the MVC way, then you can leverage client side scripting to achieve the same.

Have you considered PagedList library for pagination? All what you have to do is to reference PagedList library in your ASP.NET MVC application

To install PagedList.Mvc, run the following command in the Package Manager Console. You can use NuGet to get this package too.

PM> Install-Package PagedList.Mvc

Your viewmodel

public class QuestionViewModel
{
        public int QuestionId { get; set; }
        public string QuestionName { get; set; }
}

In your controller, reference PagedList

using PagedList;

and the Index method of your controller will be something like

public ActionResult Index(int? page)
{
            var questions = new[] {
                new QuestionViewModel { QuestionId = 1, QuestionName = "Question 1" },
                new QuestionViewModel { QuestionId = 1, QuestionName = "Question 2" },
                new QuestionViewModel { QuestionId = 1, QuestionName = "Question 3" },
                new QuestionViewModel { QuestionId = 1, QuestionName = "Question 4" }
            };

            int pageSize = 3;
            int pageNumber = (page ?? 1);
            return View(questions.ToPagedList(pageNumber, pageSize));
}

And your Index view

@model PagedList.IPagedList<ViewModel.QuestionViewModel>
@using PagedList.Mvc; 
<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />


<table>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.QuestionId)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.QuestionName)
        </td>
    </tr>
}

</table>

<br />

Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
@Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )

if in short, you need to have some endpoint on backend that returns information page by page, e.g. http://my-website.com/questions/list?start=0&count=25. Let's say it returns information in JSON format. After that you can call this endpoint from front end (browser) side using AJAX. I would recommend using jQuery AJAX. As soon as you get data on browser side, you can use jQuery again and render the information whatever you want.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!