Javascript 从部分填充剃刀部分
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5355427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Populate a Razor Section From a Partial
提问by Craig M
My main motivation for trying to do this is to get Javascript that is only required by a partial at the bottom of the page with the rest of the Javascript and not in the middle of the page where the partial is rendered.
我尝试这样做的主要动机是获取仅页面底部的部分需要的 Javascript 和其余的 Javascript,而不是在呈现部分的页面中间。
Here's a simplified example of what I'm trying to do:
这是我正在尝试做的一个简化示例:
Here is the layout with a Scripts section right before the body.
这是在正文之前带有 Scripts 部分的布局。
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
</head>
<body>
@RenderBody()
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
@RenderSection("Scripts", false)
</body>
</html>
Here's an example view using this layout.
这是使用此布局的示例视图。
<h2>This is the view</h2>
@{Html.RenderPartial("_Partial");}
@section Scripts {
<script type="text/javascript">
alert("I'm a view.");
</script>
}
And here's the partial being rendered from the view.
这是从视图中呈现的部分。
<p>This is the partial.</p>
@* this never makes it into the rendered page *@
@section Scripts {
<script type="text/javascript">
alert("I'm a partial.");
</script>
}
In this example, the markup specified in the view is placed into the section, but the markup from the partial is not. Is it possible to populate a section from a partial view with Razor? If not, what are some other methods of getting Javascript that's only needed by partials at the bottom of the page without including it globally?
在此示例中,视图中指定的标记被放置到部分中,但部分中的标记未放置。是否可以使用 Razor 从局部视图填充部分?如果没有,还有哪些其他方法可以获取仅页面底部的部分需要的 Javascript,而无需全局包含它?
采纳答案by Mr Bell
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
我处理这个问题的方法是为 HtmlHelper 类编写几个扩展方法。这允许局部视图说它们需要一个脚本,然后在布局视图中写入标记我调用我的助手方法以发出所需的脚本
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")
.
一旦你有了它,你的局部视图只需要调用@Html.RequireScript("/Path/To/Script")
.
And in the layout view's head section you call @Html.EmitRequiredScripts()
.
并在布局视图的头部部分调用@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
这样做的另一个好处是它允许您清除重复的脚本请求。如果您有多个需要给定脚本的视图/部分视图,您可以放心地假设您只会输出一次
回答by SLaks
Partial views cannot participate in their parent views' sections.
部分视图不能参与其父视图的部分。
回答by Sergi Papaseit
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:
你可以有第二个部分,只负责注入必要的 javascript。@if
如果需要,可以在块周围放置几个脚本:
@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:
这显然可以清理一下,但是,在Scripts
您的视图部分:
@section Scripts
{
@Html.Partial("_Scripts", "ScriptName_For_Partial1")
}
Again, it might not win a beauty prize but it will work.
同样,它可能不会赢得美容奖,但它会起作用。
回答by Vlad Rudenko
The more elegant way to do this is to move partial view scripts into separate file and then render it in Scripts section of view:
更优雅的方法是将部分视图脚本移动到单独的文件中,然后在视图的脚本部分呈现它:
<h2>This is the view</h2>
@Html.RenderPartial("_Partial")
@section Scripts
{
@Html.RenderPartial("_PartialScripts")
<script type="text/javascript">
alert("I'm a view script.");
</script>
}
The partial view _Partial.cshtml:
局部视图 _ Partial.cshtml:
<p>This is the partial.</p>
The partial view _PartialScripts.cshtmlwith scripts only:
部分视图 _ PartialScripts.cshtml仅包含脚本:
<script type="text/javascript">
alert("I'm a partial script!");
</script>
回答by Russ Cam
Install the Forloop.HtmlHelpersnuget package - it adds some helpers for managing scripts in partial views and editor templates.
安装Forloop.HtmlHelpersnuget 包 - 它添加了一些帮助程序来管理部分视图和编辑器模板中的脚本。
Somewhere in your layout, you need to call
在布局中的某个地方,您需要调用
@Html.RenderScripts()
This will be where any script files and script blocks will be outputted in the page so I would recommend putting it after your main scripts in the layout and after a scripts section (if you have one).
这将是任何脚本文件和脚本块将在页面中输出的地方,因此我建议将其放在布局中的主要脚本之后和脚本部分之后(如果您有)。
If you're using The Web Optimization Framework with bundling, you can use the overload
如果您使用捆绑的 Web 优化框架,则可以使用重载
@Html.RenderScripts(Scripts.Render)
so that this method is used for writing out script files.
以便此方法用于写出脚本文件。
Now, anytime you want to add script files or blocks in a view, partial view or template, simply use
现在,只要您想在视图、局部视图或模板中添加脚本文件或块,只需使用
@using (Html.BeginScriptContext())
{
Html.AddScriptFile("~/Scripts/jquery.validate.js");
Html.AddScriptBlock(
@<script type="text/javascript">
$(function() { $('#someField').datepicker(); });
</script>
);
}
The helpers ensure that only one script file reference is rendered if added multiple times and it also ensures that script files are rendered out in an expected order i.e.
如果多次添加,帮助程序确保仅呈现一个脚本文件引用,并且还确保脚本文件以预期的顺序呈现,即
- Layout
- Partials and Templates (in the order in which they appear in the view, top to bottom)
- 布局
- 部分和模板(按照它们在视图中出现的顺序,从上到下)
回答by Jean
[Updated version]Updated version following @Necrocubus question to Include inline scripts.
[更新版本]在@Necrocubus 问题之后更新版本以包含内联脚本。
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
}
My 2 cents, it is an old post, but still relevant, so here is an upgraded update of Mr Bell's solution which works with ASP.Net Core.
我的 2 美分,这是一个旧帖子,但仍然相关,所以这里是贝尔先生解决方案的升级更新,该解决方案适用于 ASP.Net Core。
It allows adding scripts and styles to the main layout from imported partial views and subviews, and possibility to add options to script/style imports (like async defer etc):
它允许从导入的部分视图和子视图向主布局添加脚本和样式,并可以向脚本/样式导入添加选项(如异步延迟等):
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; }
}
}
回答by Sebastian
For those looking for the aspnet core 2.0 version:
对于那些正在寻找 aspnet core 2.0 版本的人:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
public static class HttpContextAccessorExtensions
{
public static string RequireScript(this IHttpContextAccessor htmlContextAccessor, string path, int priority = 1)
{
var requiredScripts = htmlContextAccessor.HttpContext.Items["RequiredScripts"] as List<ResourceInclude>;
if (requiredScripts == null) htmlContextAccessor.HttpContext.Items["RequiredScripts"] = requiredScripts = new List<ResourceInclude>();
if (requiredScripts.All(i => i.Path != path)) requiredScripts.Add(new ResourceInclude() { Path = path, Priority = priority });
return null;
}
public static HtmlString EmitRequiredScripts(this IHttpContextAccessor htmlContextAccessor)
{
var requiredScripts = htmlContextAccessor.HttpContext.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; }
}
}
Add to your layout after the scripts render section call:
在脚本渲染部分调用后添加到您的布局:
@HttpContextAccessor.EmitRequiredScripts()
And in your partial view:
在你的部分观点中:
@inject IHttpContextAccessor HttpContextAccessor
...
@HttpContextAccessor.RequireScript("/scripts/moment.min.js")
回答by KyleMit
You can create a new Layout
page and wrap the PartialView inside of a Full View that is responsible for rendering the contents and also any library sections.
您可以创建一个新Layout
页面并将 PartialView 包装在负责呈现内容和任何库部分的完整视图中。
For example, let's say I have the following code:
例如,假设我有以下代码:
HomeController.cs
HomeController.cs
[HttpGet]
public ActionResult About()
{
var vm = new AboutViewModel();
return View("About", vm);
}
When the Full Page view is rendered, it's typically renderedby merging two files:
当全页面视图被渲染时,它通常是通过合并两个文件来渲染的:
About.cshtml
About.cshtml
@model AboutViewModel
@{
ViewBag.Title = "About CSHN";
}
<h3>@ViewBag.Title</h3>
@section Styles {
<style> /* style info here */ </style>
}
@section Scripts {
<script> /* script info here */ </script>
}
_Layout.cshtml
(or whatever is specified in _ViewStart or overridden in the page)
_Layout.cshtml
(或在 _ViewStart 中指定或在页面中覆盖的任何内容)
<!DOCTYPE html>
<html>
<head>
@RenderSection("Styles", false)
<title>@ViewBag.Title</title>
</head>
<body>
@RenderBody()
@RenderSection("scripts", false)
</body>
</html>
Now, suppose you wanted to Render About.cshtml
as a Partial View, perhaps as modal window in response to AJAX call. The goal here being to return only the content specified in the about page, scripts and all, without all the bloat included in the _Layout.cshtml
master layout (like a full <html>
document).
现在,假设您想About.cshtml
作为Partial View呈现,也许作为响应 AJAX 调用的模式窗口。这里的目标是只返回关于页面、脚本和所有内容中指定的内容,而不包括_Layout.cshtml
主布局中的所有膨胀(如完整<html>
文档)。
You might try it like this, but it won't come with any of the section blocks:
您可以这样尝试,但它不会附带任何部分块:
return PartialView("About", vm);
Instead, add a simpler layout page like this:
相反,添加一个更简单的布局页面,如下所示:
_PartialLayout.cshtml
_PartialLayout.cshtml
<div>
@RenderBody()
@RenderSection("Styles", false)
@RenderSection("scripts", false)
</div>
Or to support a modal window like this:
或者支持这样的模态窗口:
_ModalLayout.cshtml
_ModalLayout.cshtml
<div class="modal modal-page fade" tabindex="-1" role="dialog" >
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">@ViewBag.Title</h4>
</div>
<div class="modal-body">
@RenderBody()
@RenderSection("Styles", false)
@RenderSection("scripts", false)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-inverse" data-dismiss="modal">Dismiss</button>
</div>
</div>
</div>
</div>
Then you can specify a custom Master Viewin this controller or any other handler that you want to render the contents and scripts of a view simultaneously
然后,您可以在此控制器或任何其他要同时呈现视图的内容和脚本的处理程序中指定自定义主视图
[HttpGet]
public ActionResult About()
{
var vm = new AboutViewModel();
return !Request.IsAjaxRequest()
? View("About", vm)
: View("About", "~/Views/Shared/_ModalLayout.cshtml", vm);
}
回答by Jonathan
Here cames my solution to the frequently asked questions "how to inject sections from partial views to main views or main layout view for asp.net mvc?". If you do a search on stackoverflow by keywords "section + partial", you will get quite a big list of related questions, and given answers, but none of them are seems elegant to me by means of the razor engine grammar. So I just take a look to the Razor engine see if there could be a some better solution to this question.
这是我对常见问题的解决方案“如何将部分从部分视图注入到主视图或 asp.net mvc 的主布局视图?”。如果您通过关键字“部分 + 部分”在 stackoverflow 上进行搜索,您将获得相当多的相关问题列表,并给出了答案,但通过剃刀引擎语法,它们对我来说似乎都不优雅。所以我只是看看 Razor 引擎,看看是否有更好的解决方案来解决这个问题。
Fortunately, I found something it is interesting to me of how the Razor engine does the compilation for the view template file (*.cshtml, *.vbhtml). (I will explain later), below is my code of the solution which I think is quite simple and elegant enough in usage.
幸运的是,我发现了一些有趣的东西,即 Razor 引擎如何编译视图模板文件(*.cshtml、*.vbhtml)。(我稍后会解释),下面是我的解决方案代码,我认为在使用中非常简单和优雅。
namespace System.Web.Mvc.Html
{
public static class HtmlHelperExtensions
{
/// <summary>
/// 确保所有视图,包括分部视图(PartialView)中的节(Section)定义被按照先后顺序追加到最终文档输出流中
/// </summary>
public static MvcHtmlString EnsureSection(this HtmlHelper helper)
{
var wp = (WebViewPage)helper.ViewDataContainer;
Dictionary<string, WebPages.SectionWriter> sw = (Dictionary<string, WebPages.SectionWriter>)typeof(WebPages.WebPageBase).GetProperty("SectionWriters", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance).GetValue(wp);
if (!helper.ViewContext.HttpContext.Items.Contains("SectionWriter"))
{
Dictionary<string, Stack<WebPages.SectionWriter>> qss = new Dictionary<string, Stack<WebPages.SectionWriter>>();
helper.ViewContext.HttpContext.Items["SectionWriter"] = qss;
}
var eqs = (Dictionary<string, Stack<WebPages.SectionWriter>>)helper.ViewContext.HttpContext.Items["SectionWriter"];
foreach (var kp in sw)
{
if (!eqs.ContainsKey(kp.Key)) eqs[kp.Key] = new Stack<WebPages.SectionWriter>();
eqs[kp.Key].Push(kp.Value);
}
return MvcHtmlString.Create("");
}
/// <summary>
/// 在文档流中渲染指定的节(Section)
/// </summary>
public static MvcHtmlString RenderSectionEx(this HtmlHelper helper, string section, bool required = false)
{
if (helper.ViewContext.HttpContext.Items.Contains("SectionWriter"))
{
Dictionary<string, Stack<WebPages.SectionWriter>> qss = (Dictionary<string, Stack<WebPages.SectionWriter>>)helper.ViewContext.HttpContext.Items["SectionWriter"];
if (qss.ContainsKey(section))
{
var wp = (WebViewPage)helper.ViewDataContainer;
var qs = qss[section];
while (qs.Count > 0)
{
var sw = qs.Pop();
var os = ((WebViewPage)sw.Target).OutputStack;
if (os.Count == 0) os.Push(wp.Output);
sw.Invoke();
}
}
else if (!qss.ContainsKey(section) && required)
{
throw new Exception(string.Format("'{0}' section is not defined.", section));
}
}
return MvcHtmlString.Create("");
}
}
}
usage: To use the code is quite simple as well, and it looks almost the same style to the usual. It also supports any levels to the nested partial views. ie. I have a view template chain: _ViewStart.cshtml->layout.cshtml->index.cshtml->[head.cshtml,foot.cshtml]->ad.cshtml.
用法:使用代码也很简单,看起来和平时几乎一样的风格。它还支持嵌套局部视图的任何级别。IE。我有一个视图模板链:_ViewStart.cshtml->layout.cshtml->index.cshtml->[head.cshtml,foot.cshtml]->ad.cshtml。
In layout.cshtml, we have:
在 layout.cshtml 中,我们有:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>@ViewBag.Title - @ViewBag.WebSetting.Site.WebName</title>
<base href="@ViewBag.Template/" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Cache-Control" content="no-siteapp" />
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1.0, user-scalable=0,user-scalable=no">
<meta name="format-detection" content="telephone=no">
<meta name="renderer" content="webkit">
<meta name="author" content="Taro Technology Co.,LTD" />
<meta name="robots" content="index,follow" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<link rel="alternate icon" type="@ViewBag.WebSetting.Site.WebFavIcon" href="@ViewBag.WebSetting.Site.WebFavIcon">
@Html.RenderSectionEx("Head")
</head>
<body>
@RenderBody()
@Html.RenderSectionEx("Foot")
</body>
</html>
And in index.cshtml, we have:
在 index.cshtml 中,我们有:
@{
ViewBag.Title = "首页";
}
@Html.Partial("head")
<div class="am-container-1">
.......
</div>
@Html.Partial("foot")
And in head.cshtml, we would have the code:
在 head.cshtml 中,我们会有代码:
@section Head{
<link rel="stylesheet" href="assets/css/amazeui.css" />
<link rel="stylesheet" href="assets/css/style.css" />
}
<header class="header">
......
</header>
@Html.EnsureSection()
it is the same in foot.cshtml or ad.cshtml, you can still define Head or Foot section in them, make sure to call @Html.EnsureSection() once at the end of the partial view file. That's all you need to do to get rid of the subjected issue in asp mvc.
在foot.cshtml或ad.cshtml中是一样的,你仍然可以在其中定义Head或Foot部分,确保在局部视图文件的末尾调用@Html.EnsureSection()一次。这就是你需要做的所有事情来摆脱 asp mvc 中的问题。
I just share my code snippet so others may take use of it. If you feel it is useful, please don't hesitate to up rate my post. :)
我只是分享我的代码片段,以便其他人可以使用它。如果您觉得它有用,请不要犹豫,为我的帖子点赞。:)
回答by Evert
This functionality is also implemented in ClientDependency.Core.Mvc.dll. It provides the html helpers: @Html.RequiresJs and @Html.RenderJsHere(). Nuget package: ClientDependency-Mvc
此功能也在 ClientDependency.Core.Mvc.dll 中实现。它提供了 html 助手:@Html.RequiresJs 和 @Html.RenderJsHere()。Nuget 包:ClientDependency-Mvc