如何基于Ajax实现滚动分页加载关注用户列表?
Let's walk through how to implement dynamic loading of your following list, 5 items at a time, using Ajax and ASP.NET MVC. We'll break this into controller adjustments, view updates, and refined jQuery logic.
1. Update ViewModel to Track Pagination Data
First, modify your FollowingViewModel to include pagination metadata so we can track how many more pages are available:
public class FollowingViewModel { public IEnumerable<ApplicationUser> Following { get; set; } // Adjust type to match your Followee model public bool ShowActions { get; set; } public string Heading { get; set; } public int CurrentPage { get; set; } public int TotalItems { get; set; } public int PageSize { get; set; } = 5; // Set default page size to 5 }
2. Modify Controller for Pagination & Partial Views
We'll add two actions: one for the initial page load, and another to return partial views of subsequent pages. This keeps our Ajax calls lightweight (no full page markup):
[Authorize] public ActionResult Following() { int page = 1; int pageSize = 5; var userId = User.Identity.GetUserId(); // Get paginated initial data var following = _context.Followings .Where(x => x.FollowerId == userId) .Select(a => a.Followee) .Skip((page - 1) * pageSize) .Take(pageSize) .ToList(); // Get total count to calculate total pages var totalItems = _context.Followings .Where(x => x.FollowerId == userId) .Count(); var viewModel = new FollowingViewModel { Following = following, ShowActions = User.Identity.IsAuthenticated, Heading = "People I'm following", CurrentPage = page, TotalItems = totalItems, PageSize = pageSize }; return View("following", viewModel); } [Authorize] public ActionResult GetFollowingPartial(int page) { int pageSize = 5; var userId = User.Identity.GetUserId(); var following = _context.Followings .Where(x => x.FollowerId == userId) .Select(a => a.Followee) .Skip((page - 1) * pageSize) .Take(pageSize) .ToList(); // Return only the list items as a partial view return PartialView("_FollowingItems", following); }
3. Create a Partial View for List Items
Make a new partial view _FollowingItems.cshtml to render individual list items (this is what we'll append via Ajax):
@model IEnumerable<ApplicationUser> <!-- Match your Followee model type --> @foreach (var following in Model) { <li>@following.Name</li> }
4. Update Main View to Support Ajax Loading
Modify your main following.cshtml view to include the initial list, loading state, and JavaScript logic:
@model Gighub3.ViewModels.FollowingViewModel @{ ViewBag.Title = "Following"; } <h1>@Model.Heading</h1> <ul id="following-list"> @Html.Partial("_FollowingItems", Model.Following) </ul> <!-- Loading state (hidden by default) --> <div id="loading-indicator" style="display: none; text-align: center; padding: 1rem;"> Loading more people... </div> <script> $(document).ready(function() { // Track pagination state let currentPage = @Model.CurrentPage; const totalPages = Math.ceil(@Model.TotalItems / @Model.PageSize); let isLoading = false; // Prevent duplicate Ajax calls // Handle scroll event $(window).scroll(function() { // Trigger load when near bottom (100px offset for better UX) const isNearBottom = $(window).scrollTop() + $(window).height() >= $(document).height() - 100; if (!isLoading && isNearBottom && currentPage < totalPages) { isLoading = true; $("#loading-indicator").show(); currentPage++; // Make Ajax call for next page $.get("/Following/GetFollowingPartial", { page: currentPage }, function(data) { // Append new items to the list $("#following-list").append(data); $("#loading-indicator").hide(); isLoading = false; }).fail(function() { // Handle errors $("#loading-indicator").hide(); isLoading = false; alert("Oops, failed to load more items."); }); } }); }); </script>
Key Improvements Explained:
- Partial Views: Avoids reloading the entire page layout with each Ajax call, only returning the new list items.
- Pagination Logic: Uses
Skip()andTake()to fetch exactly 5 items per page, calculated from thepageparameter. - Loading State: Prevents duplicate Ajax requests with the
isLoadingflag and shows a loading message for better UX. - Total Pages Check: Stops making requests once all items are loaded, so we don't hit the server unnecessarily.
内容的提问来源于stack exchange,提问作者J Doe

