2011-12-20 25 views
3

我已經構建了一個粗略的HTML幫助器方法,目的是創建兩個分頁鏈接(Next和Previous)。在HtmlHelper中生成正確的Url方法

下面是視圖模型(DTO)被傳遞到輔助方法的代碼:

public class PaginationVM 
{ 
    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); } 
    } 
} 

這裏是對HTML輔助方法的代碼:

public static MvcHtmlString Paginator(this HtmlHelper htmlHelper, PaginationVM pInfo) 
{ 
    StringBuilder result = new StringBuilder(); 

    var nextPage = pInfo.CurrentPage + 1; 
    var prevPage = pInfo.CurrentPage - 1; 

    if (pInfo.CurrentPage < pInfo.TotalPages) 
    { 
     TagBuilder tagA = new TagBuilder("a"); 
     tagA.MergeAttribute("href", "page/" + nextPage); 
     tagA.InnerHtml = "Prev"; 
     tagA.AddCssClass("prev"); 
     result.Append(tagA.ToString()); 
    } 
    else 
    { 
     TagBuilder tagB = new TagBuilder("a"); 
     tagB.MergeAttribute("href", "page/" + prevPage); 
     tagB.InnerHtml = "Next"; 
     tagB.AddCssClass("next"); 
     result.Append(tagB.ToString()); 
    } 

    return MvcHtmlString.Create(result.ToString()); 
} 

以上的組合代碼似乎工作,但只能從主頁上,如果我點擊上一個鏈接[localhost:xxxx/page/2],並轉到第2頁,那麼這些鏈接變成[localhost:xxxx/page/page/2]。

我的路由看起來如下

routes.MapRoute(
    "PagingPosts/param", // Route name 
    "page/{pageId}", // /page/3 
    new { controller = "Home", action = "Index", pageId = UrlParameter.Optional }, // Parameter defaults 
    new { pageId = @"\d+" } // Constraints: pageId must be numerical 
); 

正如你可以看到這個詞頁面現已複製。我可以想出一種解決這個問題的方法,那就是告訴它從根生成一個ActionLink,並以這種方式構建我的URL,但我不知道如何在HTML幫助程序中執行此操作,以及最好的辦法是做到這一點。

任何幫助將不勝感激

謝謝。

回答

4

一個好方法是定義一個幫助器,它需要一個可以傳遞頁碼並返回生成的URL字符串的代理。這樣,分頁程序幫助程序就不會綁定到任何特定的路由,並且可以輕鬆地在整個應用程序中重用。

喜歡的東西

public static MvcHtmlString Paginator(this HtmlHelper htmlHelper, 
             PaginationVM pInfo, 
             Func<int, string> pageUrl) 
{ 
    StringBuilder result = new StringBuilder(); 

    if (pInfo.TotalPages > 1) 
    { 
     TagBuilder tag; 

     // previous link 
     if (pInfo.CurrentPage > 1) 
     { 
      tag = new TagBuilder("a"); 
      tag.MergeAttribute("href", pageUrl(pInfo.CurrentPage - 1)); 
      tag.AddCssClass("Prev"); 
      tag.InnerHtml = "previous"; 

      result.AppendLine(tag.ToString()); 
     } 

     // numbered links 
     for (int i = 1; i <= pInfo.TotalPages; i++) 
     { 
      if (i == pInfo.CurrentPage) 
      { 
       tag = new TagBuilder("span"); 
      } 
      else 
      { 
       tag = new TagBuilder("a"); 
       tag.MergeAttribute("href", pageUrl(i)); 
      } 

      tag.InnerHtml = i.ToString(); 

      result.AppendLine(tag.ToString()); 
     } 

     // next page link 
     if (pInfo.CurrentPage < pInfo.TotalPages) 
     { 
      tag = new TagBuilder("a"); 
      tag.MergeAttribute("href", pageUrl(pInfo.CurrentPage + 1)); 
      tag.AddCssClass("Next"); 
      tag.InnerHtml = "next"; 
      result.AppendLine(tag.ToString()); 
     } 
    } 

    return MvcHtmlString.Create(result.ToString()); 
} 

現在,在你看來,你可以使用它像

@Html.Paginator(pageInfo, pageId => Url.Action("Index", "Home", new { pageId })) 
+0

+1,我正要張貼看上去幾乎等同於這一個答案。除此之外,我唯一要提到的是如何使URL看起來像/ Page2 VS /?page = 2並增加了一條新路線。 – Jesse 2011-12-20 18:24:19

+0

@Jesse - 是的,如何定義路由是一個完整的其他水壺:) – 2011-12-20 18:26:22

+0

謝謝你的快速回復Russ Cam。有兩件事,請您簡單介紹一下[樂趣]是如何工作的?我查看了Microsoft的Delegate文檔,但它的理解非常複雜。 :(我也複製了你的代碼,現在我的鏈接看起來像這個[localhost:xxxx /?page = 2]而不是[localhost:xxxx/page/2]!我的路由設置爲[像這樣](http: //pastebin.com/gUXLSjJn) – Ciwan 2011-12-20 18:46:33