2012-03-11 3 views
2

У меня есть раздел для сценариев в моем _Layout.cshtml:Бритва раздел включений с частичным видом

<html> 
    <body> 
    ... 
     @RenderSection("FooterScript", required: false) 
    </body> 
</html> 

У меня есть вид «Index.cshtml», который содержит @Html.RenderPartial("LinksBlock", someModel). Для LinksBlock требуется файл сценария "links.js". Я хочу включить link.js в FooterScript из моего частичного представления, а не из основного представления (основной вид не знает о зависимостях частичного представления), и я хочу быть уверенным, что если я использую более 1 LinksBlock в своем view, только 1 link.js был включен. Является ли это возможным?

ответ

13

Разделы не работают с частичными видами. Но вы могли бы написать пару пользовательских помощников, которые могли бы быть использованы в сочетании:

public static class HtmlExtensions 
{ 
    public static IHtmlString RegisteredScripts(this HtmlHelper htmlHelper) 
    { 
     var ctx = htmlHelper.ViewContext.HttpContext; 
     var registeredScripts = ctx.Items["_scripts_"] as Stack<string>; 
     if (registeredScripts == null || registeredScripts.Count < 1) 
     { 
      return null; 
     } 
     var sb = new StringBuilder(); 
     foreach (var script in registeredScripts) 
     { 
      var scriptBuilder = new TagBuilder("script"); 
      scriptBuilder.Attributes["type"] = "text/javascript"; 
      scriptBuilder.Attributes["src"] = script; 
      sb.AppendLine(scriptBuilder.ToString(TagRenderMode.Normal)); 
     } 
     return new HtmlString(sb.ToString()); 
    } 

    public static void RegisterScript(this HtmlHelper htmlHelper, string script) 
    { 
     var ctx = htmlHelper.ViewContext.HttpContext; 
     var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext); 
     var registeredScripts = ctx.Items["_scripts_"] as Stack<string>; 
     if (registeredScripts == null) 
     { 
      registeredScripts = new Stack<string>(); 
      ctx.Items["_scripts_"] = registeredScripts; 
     } 
     var src = urlHelper.Content(script); 
     if (!registeredScripts.Contains(src)) 
     { 
      registeredScripts.Push(src); 
     } 
    } 
} 

, а затем в вашем _Layout.cshtml:

@Html.RegisteredScripts() 

и в вашем парциальное:

@{Html.RegisterScript("~/scripts/foo.js");} 
+0

Что делать, если я хотите иметь возможность добавлять файлы, разделенные как сценарием, так и сценарии, которые помещаются в частичное представление (для второго я хочу использовать ключ для идентификации и не регистрировать те же скрипты, если частичное представление отображается несколько раз)? –

+0

Я использую файлы .vsdoc и, во-вторых, хочу сохранить поддержку Intellisence (например, он не должен работать как Register ("key", ""), но Register ("key ", @ {})) –

+1

Отлично. Upvoted. Я не буду использовать это еще, но я хочу добавить его в свою кодовую базу прямо сейчас! :) –

Смежные вопросы