2009-07-12 13 views
1

In letzter Zeit habe ich mit einer nervigen Situation auf ASP.NET MVC gekämpft. Hier ist die Geschichte in Kurzform,
Ich soll eine Ansicht haben, die alle Produkte auflistet; Jetzt, weil diese Produkte zu viele sind, blog ich sie (sehr innovativ heh!). Die Seite enthält zwei Paging-Pfeile - "Nächste 10 Produkte", "und vorherige 10 Produkte". Die Ansicht wird an eine IEnumerable<Product> Sammlung übergeben, die die Liste der anzuzeigenden Produkte enthält. Der Ansicht werden auch zwei Ganzzahlen (currentPage, totalPages) als ViewData-Elemente übergeben. Was ich nun erreichen muss, ist zu überprüfen, ob es die erste Seite ist (ViewData ["CurrentPage"] == 0) Ich sollte die CSS-Klasse des "vorherige 10 Seiten" -Links auf deaktiviert ändern, also kam ich auf etwas wie das folgende

Geschachtelte serverseitige Blöcke in ASP.NET MVC?

<a href="/Products/Page<%=Html.Encode(Convert.ToInt32(ViewData["CurrentPage"])-1)%>/" 
      class="<%=Convert.ToInt32(ViewData["CurrentPage"]) <= 1 ? "bgn disabled" : ""%>">       
       previous 10 products     
     </a> 

Das funktionierte gut, noch ist es ein Problem. Obwohl die Verknüpfung deaktiviert oder speziell grau dargestellt ist, verweist sie immer noch auf eine gültige URL. Daher habe ich versucht, das href-Attribut der Verknüpfung basierend auf der CurrentPage-Variable zu ändern. Hier ist, wie der Code aussieht (bereiten Sie sich auf die reine Hässlichkeit):

<a href="<%=Convert.ToInt32(ViewData["CurrentPage"]) <= 0 ? 
     "javascript:void[]" : 
     "/products/Page<%=Html.Encode(Convert.ToInt32(ViewData["CurrentPage"])+1)%>/" %>" 
     class="<%=Convert.ToInt32(ViewData["CurrentPage"]) <= 0 ? 
     "bgn disabled" : 
     ""%>"> 

    previous 10 products 
    </a> 

Nun, meine Probleme mit diesem Code sind:

  1. Die zweite Anweisung nicht funktioniert, offenbar weil der verschachtelten Server-Seite Skripte
  2. Es ist sehr hässlich, und absolut unlesbar (stellen Sie sich vor, ich mache das mit jeder Seite, die Paging erfordert! Schmerzen in der aber). ? :(

besser Alternativen Jungs

Antwort

2

Sie können eine if Anweisung:

<% if (Convert.ToInt32(ViewData["CurrentPage"]) <= 0) { %> 
    Disabled template goes here... 
<% } else { %> 
    Link template goes here... 
<% } %> 

By the way, wenn Sie dies für eine Reihe von Seiten tun, können Sie kapseln es in einem ViewUserControl oder ein ViewMasterPage

+0

Nun, immer Rot des ternären Operator mir sehr geholfen. Es sieht jetzt besser aus, aber gibt es keinen anderen Ansatz, um dies noch mehr zu überdenken? – Galilyou

+0

Neben der Kapselung in einer Steuerungs- oder Masterseite empfehle ich, ein stark typisiertes Modell zu verwenden, anstatt "ViewData" direkt zu verwenden. Abgesehen davon können Sie auch Ihren eigenen HTML-Helfer erstellen, wenn das sinnvoll ist. –

0

Sie können meinen Pager HTML Helfer versuchen.

using System; 
using System.Text; 
using System.Web.Mvc; 
using System.Web.Routing; 

namespace System.Web.Mvc 
{ 
    public class Pager 
    { 
     private ViewContext viewContext; 
     private readonly int pageSize; 
     private readonly int currentPage; 
     private readonly int totalItemCount; 
     private readonly RouteValueDictionary linkWithoutPageValuesDictionary; 

     public Pager(ViewContext viewContext, int pageSize, int currentPage, int totalItemCount, RouteValueDictionary valuesDictionary) 
     { 
     this.viewContext = viewContext; 
     this.pageSize = pageSize; 
     this.currentPage = currentPage; 
     this.totalItemCount = totalItemCount; 
     this.linkWithoutPageValuesDictionary = valuesDictionary; 
     } 

     public string RenderHtml() 
     { 
     int pageCount = (int)Math.Ceiling(this.totalItemCount/(double)this.pageSize); 
     int nrOfPagesToDisplay = 8; 

     var sb = new StringBuilder(); 
     sb.Append("<ul class=\"pagination\">"); 
     // Previous 
     if (this.currentPage > 1) 
     { 
      sb.Append(string.Format("<li class=\"prev\"><a href=\"{0}\">«</a></li>", Route(this.currentPage - 1))); 
     } 
     else 
     { 
      sb.Append("<li class=\"prev disabled\"><span>«</span></li>"); 
     } 

     int start = 1; 
     int end = pageCount; 

     if (pageCount > nrOfPagesToDisplay) 
     { 
      int middle = (int)Math.Ceiling(nrOfPagesToDisplay/2d) - 1; 
      int below = (this.currentPage - middle); 
      int above = (this.currentPage + middle); 

      if (below < 4) 
      { 
       above = nrOfPagesToDisplay; 
       below = 1; 
      } 
      else if (above > (pageCount - 4)) 
      { 
       above = pageCount; 
       below = (pageCount - nrOfPagesToDisplay); 
      } 

      start = below; 
      end = above; 
     } 

     if (start > 3) 
     { 
      sb.Append(GeneratePageLink("1", 1)); 
      sb.Append(GeneratePageLink("2", 2)); 
       sb.Append("<li class=\"more\">...</li>"); 
     } 
     for (int i = start; i <= end; i++) 
     { 
      if (i == this.currentPage) 
      { 
       sb.Append(string.Format("<li class=\"page selected\"><span>{1}</span></li>", Route(i),i)); 
      } 
      else 
      { 
       sb.Append(GeneratePageLink(i.ToString(), i)); 
      } 
     } 
     if (end < (pageCount - 3)) 
     { 
       sb.Append("<li class=\"more\">...</li>"); 
      sb.Append(GeneratePageLink((pageCount - 1).ToString(), pageCount - 1)); 
      sb.Append(GeneratePageLink(pageCount.ToString(), pageCount)); 
     } 

     // Next 
     if (this.currentPage < pageCount) 
     { 
      sb.Append(string.Format("<li class=\"next\"><a href=\"{0}\">»</a></li>", Route(this.currentPage + 1))); 
     } 
     else 
     { 
      sb.Append("<li class=\"next disabled\"><span>»</span></li>"); 
     } 
     sb.Append("</ul>"); 
     return sb.ToString(); 
     } 
     private string Route(int pageNumber) 
     { 

     var pageLinkValueDictionary = new RouteValueDictionary(this.linkWithoutPageValuesDictionary); 
     pageLinkValueDictionary.Add("page", pageNumber); 
     var virtualPathData = RouteTable.Routes.GetVirtualPath(this.viewContext.RequestContext, pageLinkValueDictionary); 
     return virtualPathData.VirtualPath; 

     } 
     private string GeneratePageLink(string linkText, int pageNumber) 
     { 
     var pageLinkValueDictionary = new RouteValueDictionary(this.linkWithoutPageValuesDictionary); 
     pageLinkValueDictionary.Add("page", pageNumber); 
     var virtualPathData = RouteTable.Routes.GetVirtualPath(this.viewContext.RequestContext, pageLinkValueDictionary); 

     if (virtualPathData != null) 
     { 

      string linkFormat = "<li class=\"page\"><a href=\"{0}\">{1}</a></li>"; 
      return String.Format(linkFormat, virtualPathData.VirtualPath, linkText); 
     } 
     else 
     { 
      return null; 
     } 
     } 
    } 
} 

Wie zu verwenden:

<%= Html.Pager(10, (Request["page"].IsNotNull() ? Request["page"].ToInt() : 1), ViewData["Total"].ToInt(), new { category = Request["category"], alphabet = Request["alphabet"] })%> 

und Controller-Implementierung wie folgt aussieht:

public ActionResult Index(string page, string category, string alphabet) 
{ 
    ..... 
    ViewData["Total"] = model.Count(); 
    return View(model.ToPagedList((page.IsNotNull() ? page.ToInt() - 1 : 0), 10)); 
} 

Und schließlich Ausgabe:

pager http://clip2net.com/clip/m12007/1247389672-clip-1kb.png

+0

Nun, eigentlich versuche ich nur zwei Links zu haben [vorherige 10 und nächste 10]. Ich bin mir nicht sicher, ob Ihre Pager-Hilfsmethode dabei helfen kann. Trotzdem danke. – Galilyou

+0

Willkommen, kein Problem: _) – omoto

1

Hier ist eine andere Lösung. In <script runat="server">:

<script runat="server"> 
    protected string Prev10Url { 
     get { 
      return Convert.ToInt32(ViewData["CurrentPage"]) <= 0 
       ? "javascript:void[]" 
       : "/products/Page" + Html.Encode(Convert.ToInt32(ViewData["CurrentPage"])+1); 
     } 
    } 

    protected string Prev10Class { 
     get { 
      return Convert.ToInt32(ViewData["CurrentPage"]) <= 0 
       ? "bgn disabled" 
       : ""; 
     } 
    } 

    protected string Next10Url { 
     get { 
      ... 
     } 
    } 

    protected string Next10Class { 
     get { 
      ... 
     } 
    } 
</script> 

Und dann ändern Sie Ihr Markup:

<a href="<%= Prev10Url %>" class="<%= Prev10Class %>">previous 10 products</a> 
<a href="<%= Next10Url %>" class="<%= Next10Class %>">next 10 products</a> 
+0

+1 sauberer als das Chaos ich kam sowieso :) – Galilyou