What would be the best way to load, for example, the first 25 items of the IEnumerable
of an Index view in ASP.NET MVC?
I have a model and have created a controller and views using scaffolding. In the index page I create a div
containing some info for each instance in the model of the view (List
of Question objects). I would like to display the first 25 items and give the user the possibility to load more using a link at the bottom saying "Load the next 25 questions...".
How would this be possible?
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.
来源:https://stackoverflow.com/questions/22924565/how-to-load-first-x-items-and-give-user-the-option-to-load-more-in-mvc-net