I am wondering what the best practice is for including javascript files inside partial views. Once rendered this will end up as a js include tag in the middle of my page\'s
Today I've created my own solution which fits the bill perfectly. Whether it is good design or not, is for you all to decide but thought I should share either way!
Below is my HtmlExtensions class which allows you to do this in your masterpage:
<%=Html.RenderJScripts() %>
My HtmlExtensions class:
public static class HtmlExtensions
{
private const string JSCRIPT_VIEWDATA = "__js";
#region Javascript Inclusions
public static void JScript(this HtmlHelper html, string scriptLocation)
{
html.JScript(scriptLocation, string.Empty);
}
public static void JScript(this HtmlHelper html, string scriptLocationDebug, string scriptLocationRelease)
{
if (string.IsNullOrEmpty(scriptLocationDebug))
throw new ArgumentNullException("fileName");
string jsTag = "";
#if DEBUG
jsTag = string.Format(jsTag, scriptLocationDebug);
#else
jsTag = string.Format(jsTag, !string.IsNullOrEmpty(scriptLocationRelease) ? scriptLocationRelease : scriptLocationDebug);
#endif
registerJScript(html, jsTag);
}
public static MvcHtmlString RenderJScripts(this HtmlHelper html)
{
List jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List;
string result = string.Empty; ;
if(jscripts != null)
{
result = string.Join("\r\n", jscripts);
}
return MvcHtmlString.Create(result);
}
private static void registerJScript(HtmlHelper html, string jsTag)
{
List jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List;
if(jscripts == null) jscripts = new List();
if(!jscripts.Contains(jsTag))
jscripts.Add(jsTag);
html.ViewContext.TempData[JSCRIPT_VIEWDATA] = jscripts;
}
#endregion
}
What is going on?
The class above will extend the HtmlHelper with methods to add javascript links to a collection that is being stored by the HtmlHelper.ViewContext.TempData
collection. At the end of the masterpage I put the <%=Html.RenderJScripts() %>
which will loop the jscripts collection inside the HtmlHelper.ViewContext.TempData
and render these to the output.
There is a downside however,.. You have to ensure that you don't render the scripts before you've added them. If you'd want to do this for css links for example, it wouldn't work because you have to place these in the tag of your page and the htmlhelper would render the output before you've even added a link.