Populate a Razor Section From a Partial
The way I dealt with this is to write a couple extension methods to the HtmlHelper class. That allows partials views to say that they require a script, and then in the layout view that writes the tag I call to my helper method to emit the required scripts
Here are the helper methods:
public static string RequireScript(this HtmlHelper html, string path, int priority = 1){ var requiredScripts = HttpContext.Current.Items["RequiredScripts"] as List<ResourceInclude>; if (requiredScripts == null) HttpContext.Current.Items["RequiredScripts"] = requiredScripts = new List<ResourceInclude>(); if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path, Priority = priority }); return null;}public static HtmlString EmitRequiredScripts(this HtmlHelper html){ var requiredScripts = HttpContext.Current.Items["RequiredScripts"] as List<ResourceInclude>; if (requiredScripts == null) return null; StringBuilder sb = new StringBuilder(); foreach (var item in requiredScripts.OrderByDescending(i => i.Priority)) { sb.AppendFormat("<script src=\"{0}\" type=\"text/javascript\"></script>\n", item.Path); } return new HtmlString(sb.ToString());}public class ResourceInclude{ public string Path { get; set; } public int Priority { get; set; }}
Once you have that in place your partial view just needs to call @Html.RequireScript("/Path/To/Script")
.
And in the layout view's head section you call @Html.EmitRequiredScripts()
.
An added bonus of this is that it allows you to weed out duplicate script requests. If you have multiple views/partial views that need a given script you can safely assume that you will only output it once
You could have a second partial that is only in charge of injecting the necessary javascript. Place several scripts in there around @if
blocks, if you want:
@model string@if(Model == "bla") { <script type="text/javascript">...</script>}@else if(Model == "bli") { <script type="text/javascript">...</script>}
This could obviously be cleaned up a bit, but then, in the Scripts
section of your view:
@section Scripts{ @Html.Partial("_Scripts", "ScriptName_For_Partial1")}
Again, it might not win a beauty prize but it will work.