Вложенные серверные блоки в ASP.NET MVC? - PullRequest
1 голос
/ 12 июля 2009

В последнее время я боролся с досадной ситуацией в ASP.NET MVC. Вот история вкратце,
Я должен иметь представление, в котором перечислены все продукты; сейчас, потому что этих продуктов слишком много, я делаю пейджинг (очень инновационный хех!). Страница содержит две стрелки на странице - «Следующие 10 товаров», «и предыдущие 10 товаров». Представлению передается коллекция IEnumerable<Product>, содержащая список продуктов для отображения. Представлению также передаются два целых числа (currentPage, totalPages) как элементы ViewData. Теперь мне нужно проверить, является ли это первой страницей (ViewData ["CurrentPage"] == 0). Мне следует изменить класс css ссылки "предыдущие 10 страниц" на отключенный, поэтому я придумал что-то вроде следующий

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

Это сработало нормально, но проблема есть. Хотя ссылка отключена или специально выделена серым цветом, она все же указывает на действительный URL, поэтому я попытался изменить атрибут href ссылки на основе переменной CurrentPage. Вот как выглядит код (будьте готовы к чистому безобразию):

<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>

Теперь у меня проблемы с этим кодом:

  1. Второй оператор не работает, по-видимому, из-за вложенных серверных сценариев
  2. Это очень уродливо и абсолютно нечитаемо (представьте, что я делаю это с каждой страницей, требующей подкачки! Боль в но). :(

Есть ли лучшие альтернативы, ребята?

Ответы [ 3 ]

2 голосов
/ 12 июля 2009

Вы можете использовать оператор if:

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

Кстати, если вы делаете это для набора страниц, вы можете инкапсулировать его в ViewUserControl или ViewMasterPage.

1 голос
/ 12 июля 2009

Вот еще одно решение. Добавить <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>

А затем измените разметку:

<a href="<%= Prev10Url %>" class="<%= Prev10Class %>">previous 10 products</a>
<a href="<%= Next10Url %>" class="<%= Next10Class %>">next 10 products</a>
0 голосов
/ 12 июля 2009

Вы можете попробовать мой помощник HTML пейджера:

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;
         }
      }
   }
}

Как использовать:

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

А реализация контроллера выглядит так:

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

И, наконец, вывод:

pager
(source: clip2net.com )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...