[Phiên bản cập nhật] Phiên bản
cập nhật sau câu hỏi @Necrocubus để Bao gồm các tập lệnh nội tuyến.
public static class ScriptsExtensions
{
const string REQ_SCRIPT = "RequiredScript";
const string REQ_INLINESCRIPT = "RequiredInlineScript";
const string REQ_STYLE = "RequiredStyle";
#region Scripts
/// <summary>
/// Adds a script
/// </summary>
/// <param name="html"></param>
/// <param name="path"></param>
/// <param name="priority">Ordered by decreasing priority </param>
/// <param name="bottom"></param>
/// <param name="options"></param>
/// <returns></returns>
public static string RequireScript(this IHtmlHelper html, string path, int priority = 1, bool bottom=false, params string[] options)
{
var ctxt = html.ViewContext.HttpContext;
var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceToInclude>;
if (requiredScripts == null) ctxt.Items[REQ_SCRIPT] = requiredScripts = new List<ResourceToInclude>();
if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceToInclude() { Path = path, Priority = priority, Options = options, Type=ResourceType.Script, Bottom=bottom});
return null;
}
/// <summary>
///
/// </summary>
/// <param name="html"></param>
/// <param name="script"></param>
/// <param name="priority">Ordered by decreasing priority </param>
/// <param name="bottom"></param>
/// <returns></returns>
public static string RequireInlineScript(this IHtmlHelper html, string script, int priority = 1, bool bottom = false)
{
var ctxt = html.ViewContext.HttpContext;
var requiredScripts = ctxt.Items[REQ_INLINESCRIPT] as List<InlineResource>;
if (requiredScripts == null) ctxt.Items[REQ_INLINESCRIPT] = requiredScripts = new List<InlineResource>();
requiredScripts.Add(new InlineResource() { Content=script, Priority = priority, Bottom=bottom, Type=ResourceType.Script});
return null;
}
/// <summary>
/// Just call @Html.EmitRequiredScripts(false)
/// at the end of your head tag and
/// @Html.EmitRequiredScripts(true) at the end of the body if some scripts are set to be at the bottom.
/// </summary>
public static HtmlString EmitRequiredScripts(this IHtmlHelper html, bool bottom)
{
var ctxt = html.ViewContext.HttpContext;
var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceToInclude>;
var requiredInlineScripts = ctxt.Items[REQ_INLINESCRIPT] as List<InlineResource>;
var scripts = new List<Resource>();
scripts.AddRange(requiredScripts ?? new List<ResourceToInclude>());
scripts.AddRange(requiredInlineScripts ?? new List<InlineResource>());
if (scripts.Count==0) return null;
StringBuilder sb = new StringBuilder();
foreach (var item in scripts.Where(s=>s.Bottom==bottom).OrderByDescending(i => i.Priority))
{
sb.Append(item.ToString());
}
return new HtmlString(sb.ToString());
}
#endregion Scripts
#region Styles
/// <summary>
///
/// </summary>
/// <param name="html"></param>
/// <param name="path"></param>
/// <param name="priority">Ordered by decreasing priority </param>
/// <param name="options"></param>
/// <returns></returns>
public static string RequireStyle(this IHtmlHelper html, string path, int priority = 1, params string[] options)
{
var ctxt = html.ViewContext.HttpContext;
var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceToInclude>;
if (requiredScripts == null) ctxt.Items[REQ_STYLE] = requiredScripts = new List<ResourceToInclude>();
if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceToInclude() { Path = path, Priority = priority, Options = options });
return null;
}
/// <summary>
/// Just call @Html.EmitRequiredStyles()
/// at the end of your head tag
/// </summary>
public static HtmlString EmitRequiredStyles(this IHtmlHelper html)
{
var ctxt = html.ViewContext.HttpContext;
var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceToInclude>;
if (requiredScripts == null) return null;
StringBuilder sb = new StringBuilder();
foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
{
sb.Append(item.ToString());
}
return new HtmlString(sb.ToString());
}
#endregion Styles
#region Models
public class InlineResource : Resource
{
public string Content { get; set; }
public override string ToString()
{
return "<script>"+Content+"</script>";
}
}
public class ResourceToInclude : Resource
{
public string Path { get; set; }
public string[] Options { get; set; }
public override string ToString()
{
switch(Type)
{
case ResourceType.CSS:
if (Options == null || Options.Length == 0)
return String.Format("<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\" />\n", Path);
else
return String.Format("<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\" {1} />\n", Path, String.Join(" ", Options));
default:
case ResourceType.Script:
if (Options == null || Options.Length == 0)
return String.Format("<script src=\"{0}\" type=\"text/javascript\"></script>\n", Path);
else
return String.Format("<script src=\"{0}\" type=\"text/javascript\" {1}></script>\n", Path, String.Join(" ", Options));
}
}
}
public class Resource
{
public ResourceType Type { get; set; }
public int Priority { get; set; }
public bool Bottom { get; set; }
}
public enum ResourceType
{
Script,
CSS
}
#endregion Models
}
2 xu của tôi, đó là một bài đăng cũ, nhưng vẫn còn phù hợp, vì vậy đây là bản cập nhật nâng cấp của giải pháp Mr Bell hoạt động với ASP.Net Core.
Nó cho phép thêm các tập lệnh và kiểu vào bố cục chính từ các chế độ xem từng phần và chế độ xem phụ đã nhập và khả năng thêm các tùy chọn vào nhập tập lệnh / kiểu (như async defer, v.v.):
public static class ScriptsExtensions
{
const string REQ_SCRIPT = "RequiredScript";
const string REQ_STYLE = "RequiredStyle";
public static string RequireScript(this IHtmlHelper html, string path, int priority = 1, params string[] options)
{
var ctxt = html.ViewContext.HttpContext;
var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceInclude>;
if (requiredScripts == null) ctxt.Items[REQ_SCRIPT] = requiredScripts = new List<ResourceInclude>();
if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path, Priority = priority, Options = options });
return null;
}
public static HtmlString EmitRequiredScripts(this IHtmlHelper html)
{
var ctxt = html.ViewContext.HttpContext;
var requiredScripts = ctxt.Items[REQ_SCRIPT] as List<ResourceInclude>;
if (requiredScripts == null) return null;
StringBuilder sb = new StringBuilder();
foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
{
if (item.Options == null || item.Options.Length == 0)
sb.AppendFormat("<script src=\"{0}\" type=\"text/javascript\"></script>\n", item.Path);
else
sb.AppendFormat("<script src=\"{0}\" type=\"text/javascript\" {1}></script>\n", item.Path, String.Join(" ", item.Options));
}
return new HtmlString(sb.ToString());
}
public static string RequireStyle(this IHtmlHelper html, string path, int priority = 1, params string[] options)
{
var ctxt = html.ViewContext.HttpContext;
var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceInclude>;
if (requiredScripts == null) ctxt.Items[REQ_STYLE] = requiredScripts = new List<ResourceInclude>();
if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path, Priority = priority, Options = options });
return null;
}
public static HtmlString EmitRequiredStyles(this IHtmlHelper html)
{
var ctxt = html.ViewContext.HttpContext;
var requiredScripts = ctxt.Items[REQ_STYLE] as List<ResourceInclude>;
if (requiredScripts == null) return null;
StringBuilder sb = new StringBuilder();
foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))
{
if (item.Options == null || item.Options.Length == 0)
sb.AppendFormat("<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\" />\n", item.Path);
else
sb.AppendFormat("<link rel=\"stylesheet\" href=\"{0}\" type=\"text/css\" {1} />\n", item.Path, String.Join(" ", item.Options));
}
return new HtmlString(sb.ToString());
}
public class ResourceInclude
{
public string Path { get; set; }
public int Priority { get; set; }
public string[] Options { get; set; }
}
}