MVC Html.PagedListPager() - 如何更新当前页面按钮?

时间:2015-02-25 16:42:11

标签: ajax button model-view-controller pagination

我有一个使用Html.PagedListPager()来呈现分页控件的视图。

一切正常,但在Ajax请求成功完成后,当前页面按钮不会更新。

与分页按钮关联的HTML代码的class属性应设置为active

我该怎么做?

这是创建分页控件的代码:

@Html.PagedListPager(
  Model.Items, 
  page => Url.Action("RenderMessageListItems", new { page }), 
  PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(
    new PagedListRenderOptions {Display = PagedListDisplayMode.IfNeeded},
    new System.Web.Mvc.Ajax.AjaxOptions {OnSuccess = "OnPageChanged", UpdateTargetId = Model.Name + "Items"}
  )
)

编辑:

也许我应该从包含页码的控制器返回一些JSON数据(而不是纯HTML页面)。通过这样做,我将能够更新OnSuccess Ajax函数中的相关按钮,但是还有其他方法吗?

2 个答案:

答案 0 :(得分:1)

要么我不理解PagedList库,要么它中有一个导致它奇怪行为的错误(很可能是因为这个库现在已经3年了)。我的解决方法如下,使得@Html.PagedListPager()几乎无用,我可以在所花费的时间内编写自己的代码。

控制器操作

public System.Web.Mvc.ActionResult RenderMessageListItems(int? page)
{
  ...
  System.Linq.IQueryable<Models.Message> lQuery = from m in lDBContext.Messages orderby m.CreateTimestamp select m;

  int lPageNumber = page.HasValue ? page.Value : 1;
  int lPageSize = 5;

  // note: ViewModels.MessageListItems implements IPagedList.IPagedList
  ViewModels.MessageListItems lViewModel = new ViewModels.MessageListItems(lPageNumber, lPageSize, lQuery.Count());

  lQuery = lQuery.Skip(lPageSize * (lPageNumber - 1)).Take(lPageSize);

  foreach (Models.Message lMessage in lQuery)
  {
    ViewModels.MessageListItem lMessageListItem = new ViewModels.MessageListItem();
    lMessageListItem.ID = lMessage.ID;
    lMessageListItem.Date = lMessage.Date;
    lMessageListItem.Caption = lMessage.Caption;
    lMessageListItem.Content = lMessage.Content;

    lViewModel.Add(lMessageListItem);
  }

  return Json(new {page = page, items = RenderRazorViewToString("../Shared/MessageList/Items", lViewModel)}, System.Web.Mvc.JsonRequestBehavior.AllowGet);
}

将视图传递给Json对象会导致序列化时出现循环引用异常,从而调用RenderRazorViewToString()。此功能的代码已发布在此处:https://stackoverflow.com/a/2759898/3936440

部分视图

...

@* the following include is needed to get Html.PagedListPager() working *@
<script src="@Html.ResourceUrl("Script", "jQuery.Ajax.Unobtrusive")"></script>

<script>

  function OnPageChanged(jsonObject, textStatus, jqXHR)
  {
    @* inject new items into message list *@
    $("[name=@{@Model.Name}Items]").html(jsonObject.items);

    @* select all page buttons *@
    var $buttons = $(".pagination li");

    @* get button linked to previous page and... *@
    var $previousButton = $buttons.filter(".active");

    @* remove active indication and... *@
    $previousButton.removeClass("active");

    @* fix missing link attributes of first page button (strangely PagedListPager wont render those) *@
    if ($previousButton.index() == 0)
    {
      var previousPageNumber = $previousButton.index() + 1;

      var $previousLink = $previousButton.find("a");
      $previousLink.attr("data-ajax", true);
      $previousLink.attr("data-ajax-success", "OnPageChanged");
      $previousLink.attr("href", "@Url.Action("RenderMessageListItems")?page=" + previousPageNumber);
    }

    @* set current page button to active *@
    var $currentButton = $buttons.eq(jsonObject.page - 1);
    $currentButton.addClass("active");
  }

</script>

...

@Html.PagedListPager(
  Model.Items, 
  page => Url.Action("RenderMessageListItems", new {page}), 
  PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(
    new PagedListRenderOptions {Display = PagedListDisplayMode.IfNeeded, DisplayLinkToNextPage = PagedListDisplayMode.Never},
    new System.Web.Mvc.Ajax.AjaxOptions {OnSuccess = "OnPageChanged"}
  )
)

如您所见,OnPageChanged()中的代码修复了PagedListPager的非工作部分。遗憾的是,我无法使用像下一页/上一页按钮这样的好功能,因为PagedListPager也无法正确呈现这些功能。

答案 1 :(得分:1)

我还让控件没有刷新当前页面按钮,但在我的情况下,我使用了一个名为&#34; page&#34;的变量,它(看起来像)似乎需要控件才能正常工作。 / p>