2012-06-27 2 views
1

У меня есть список объектов, которые используют пейджинг в моем доме> index.cshtml. Когда пользователь нажимает на каждую страницу объектов, я хочу только обновить эту часть страницы и ничего больше. Как бы я это сделал?MVC3 - Asynchronous Pagenation

В идеале я хочу использовать ASync методы и ControllerActions ...

Контроллеры> HomeController.cs

public ViewResult Index(int page = 1) { 
ProductsListViewModel viewModel = new ProductsListViewModel { 
Products = repository.Products 
.OrderBy(p => p.ProductID) 
.Skip((page - 1) * PageSize) 
.Take(PageSize), 
PagingInfo = new PagingInfo { 
CurrentPage = page, 
ItemsPerPage = PageSize, 
TotalItems = repository.Products.Count() 
} 
}; 
return View(viewModel); 
} 

Главная> Index.cshtml:

@model SportsStore.WebUI.Models.ProductsListViewModel 
@{ 
ViewBag.Title = "Products"; 
} 
@foreach (var p in Model.Products) { 
<div class="item"> 
<h3>@p.Name</h3> 
@p.Description 
<h4>@p.Price.ToString("c")</h4> 
</div> 
} 
<div class="pager"> 
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x})) 
</div> 

HtmlHelper> PagingHelper.cs

namespace SportsStore.WebUI.HtmlHelpers { 
public static class PagingHelpers { 
public static MvcHtmlString PageLinks(this HtmlHelper html, 
PagingInfo pagingInfo, 
Func<int, string> pageUrl) { 
StringBuilder result = new StringBuilder(); 
for (int i = 1; i <= pagingInfo.TotalPages; i++) { 
TagBuilder tag = new TagBuilder("a"); // Construct an <a> tag 
tag.MergeAttribute("href", pageUrl(i)); 
tag.InnerHtml = i.ToString(); 
if (i == pagingInfo.CurrentPage) 
tag.AddCssClass("selected"); 
result.Append(tag.ToString()); 
} 
return MvcHtmlString.Create(result.ToString()); 
} 
} 
} 
+0

есть вы сетка помещается в частичном виде – Yasser

ответ

3

Вы можете использовать AJAX. Первый шаг, чтобы поместить содержимое, которое вы хотите быть обновлена ​​в частичное и в свой собственный DIV:

@model SportsStore.WebUI.Models.ProductsListViewModel 
@{ 
    ViewBag.Title = "Products"; 
} 

<div id="products"> 
    @Html.Partial("_products", Model.Products) 
</div> 

<div class="pager"> 
    @Html.PageLinks(Model.PagingInfo, x => Url.Action("Index", new { page = x })) 
</div> 

и тогда, конечно, вы будете иметь соответствующий _Products.cshtml парциальное:

@model IEnumerable<SportsStore.WebUI.Models.ProductViewModel> 
@foreach (var p in Model.Products) { 
    <div class="item"> 
     <h3>@p.Name</h3> 
     @p.Description 
     <h4>@p.Price.ToString("c")</h4> 
    </div> 
} 

и затем адаптировать действие контроллера, так что она способна реагировать на AJAX запросы:

public ActionResult Index(int page = 1) 
{ 
    var viewModel = new ProductsListViewModel 
    { 
     Products = repository.Products 
      .OrderBy(p => p.ProductID) 
      .Skip((page - 1) * PageSize) 
      .Take(PageSize), 
     PagingInfo = new PagingInfo 
     { 
      CurrentPage = page, 
      ItemsPerPage = PageSize, 
      TotalItems = repository.Products.Count() 
     } 
    }; 
    if (Request.IsAjaxRequest()) 
    { 
     return PartialView("_Products", viewModel); 
    } 

    return View(viewModel); 
} 

и теперь все, что осталось, это AJAXify ваших якорей нумерации страниц , Может быть сделано в отдельном файла JavaScript, где вы могли бы использовать JQuery, чтобы подписаться на .click() случае их и заменить действие по умолчанию с просьбой AJAX:

$(function() { 
    $('.pager a').click(function() { 
     $.ajax({ 
      url: this.href, 
      type: 'GET', 
      cache: false, 
      success: function(products) { 
       $('#products').html(products); 
      } 
     }); 

     // prevent the default redirect 
     return false; 
    }); 
}); 
+0

Изменяя возвращение тип вашего действия «Index» от «ViewResult» до «ActionResult». Я обновил свой ответ. Я не заметил, что вы изменили это. Вы всегда должны оставить «ActionResult» в качестве возвращаемого типа для своих действий, который является наивысшим классом в иерархии результатов. –

+0

Нет, 'return PartialView (« _ Products », viewModel);' не следует включать мастер-макет. Вы уверены, что запрос AJAX работал и что вы ввели условие 'if'? –

+0

Вы получаете ошибку 500. Есть ли исключение, вызванное действием вашего контроллера? Или пока рендеринг частичного? Используйте FireBug, чтобы изучить ответ AJAX-запроса и увидеть точную причину этой ошибки. Тот факт, что у вас есть 2 пейджера, не должен ничего менять или усложнять. Он должен работать. –