Помощник вкладок MVC3

#asp.net-mvc #asp.net-mvc-3

#asp.net-mvc #asp.net-mvc-3

Вопрос:

Мне нужен html-помощник, который бы заботился о функциональности «вкладок» на странице. нажатие на вкладки приведет к повторной загрузке страницы и частичному просмотру (если указано). Я написал это примерно так, но не уверен, что это лучшее решение.??

 public static class TabExtensions
{
    public static MvcHtmlString Tabs(this HtmlHelper htmlHelper, List<TabItem> tabItems, object htmlAttributes = null)
    {
        if (tabItems == null)
        {
            throw new ArgumentException("at least one tab item required");
        }

        string viewName = string.Empty;
        object model = null;
        var sb = new StringBuilder();
        sb.Append("<a name="tabs"></a>");

        var tagUl = new TagBuilder("ul");
        tagUl.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));

        // Current url data
        var baseUri = new UriBuilder(htmlHelper.ViewContext.HttpContext.Request.Url);
        var selTab = htmlHelper.ViewContext.RequestContext.HttpContext.Request.QueryString["tab"];

        foreach (var tab in tabItems)
        {
            // No tab user selected
            if (string.IsNullOrEmpty(selTab))
            {
                selTab = tab.TabLinkText;
            }

            var tagLi = new TagBuilder("li");
            string tagInnerHtml;

            if (selTab.Equals(tab.TabLinkText, StringComparison.OrdinalIgnoreCase))
            {
                tagLi.MergeAttribute("class", "current");
                tagInnerHtml = string.Format("<strong>{0}</strong>", tab.Text);
                viewName = tab.PartialViewName;
                model = tab.PartialViewModel;
            }
            else
            {
                tagInnerHtml = tab.Text;
            }

            var queryToAppend = string.Concat("tab=", tab.TabLinkText);
            var querystring = new StringBuilder();

            if (baseUri.Query.Length > 1)
            {
                if (baseUri.Query.Contains("tab"))
                {
                    querystring.Append(baseUri.Query.Replace(string.Concat("tab=", selTab), queryToAppend));
                }
                else
                {
                    querystring.Append(baseUri.Query   "amp;"   queryToAppend);
                }
            } 
            else
            {
                querystring.Append("?"   queryToAppend);
            }

            // Assign anchor link
            querystring.Append("#tabs");

            tagLi.InnerHtml = string.Format("<a href="{0}">{1}</a>", querystring, tagInnerHtml);
            tagUl.InnerHtml  = tagLi.ToString();
        }

        sb.Append(tagUl.ToString());

        // Render partial
        if (!string.IsNullOrEmpty(viewName))
        {
            htmlHelper.ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(htmlHelper.ViewContext.Controller.ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(htmlHelper.ViewContext.Controller.ControllerContext, viewResult.View, htmlHelper.ViewData, htmlHelper.ViewContext.TempData, sw);
                viewResult.View.Render(viewContext, sw);

                sb.Append(sw.GetStringBuilder().ToString());
            }
        }

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

#region Tab Item Model 

public class TabItem
{
    public string Text { get; set; }

    public string TabLinkText { get; set; }

    public string PartialViewName { get; set; }

    public object PartialViewModel { get; set; }

    public TabItem(string text, string tabLinkText)
        : this()
    {
        this.Text = text;
        this.TabLinkText = tabLinkText;
    }

    public TabItem(string text, string tabLinkText, string partialViewName, object partialViewModel = null)
        : this()
    {
        this.Text = text;
        this.TabLinkText = tabLinkText;
        this.PartialViewName = partialViewName;
        this.PartialViewModel = partialViewModel;
    }

    public TabItem()
    {
        this.Text = string.Empty;
        this.PartialViewName = string.Empty;
        this.TabLinkText = string.Empty;
        this.PartialViewModel = null;
    }
}

#endregion
  

Вы используете его следующим образом:

                     <%
                        var tabList = new List<TabItem>
                        {
                            new TabItem(LocalResources.fld_AboutFirm_lbl, "about"),
                            new TabItem(LocalResources.fld_FirmOffers_lbl, "offer"),
                            new TabItem(LocalResources.fld_Profile_lbl, "profile", "~/Views/Partial/FirmProfileTab.cshtml", Model),
                            new TabItem(LocalResources.fld_Contact_lbl, "contact", "~/Views/Partial/FirmContactTab.cshtml", Model)
                        };
                    %>
                    <%: Html.Tabs(tabList, new { @class = "firmTabs clearfix" })%>
  

это приведет к созданию html:

 <ul class="firmTabs clearfix"><li><a href="?tab=about#tabs">O firmie</a></li><li><a href="?tab=offer#tabs">Firma oferuje</a></li><li><a href="?tab=profile#tabs">Profil</a></li><li class="current"><a href="?tab=contact#tabs"><strong>Kontakt</strong></a></li></ul>
  

Комментарии:

1. У вас есть конкретная проблема? Или вы просто ищете комментарии повторно. ваш код? Если последнее, то оно, вероятно, более уместно на refactormycode.com

Ответ №1:

Я думаю, что лучшим решением является создание главной страницы для меню вкладок и просмотра страниц для содержимого вкладок. Ваш подход выглядит для меня очень сложным. Зачем вам для этого нужен html helper? Если вы инкапсулируете свой HTML-код в вспомогательный метод — вы потеряете свой вид. Итак, с точки зрения MVC ваш способ, я думаю, не очень хорош.