情况如下:
在MVC应用程序中,我有一个部分,它正在呈现一个脚本 bundle 。 这部分被渲染了几次。
是否有内置方式确定特定的捆绑 在之前在页面的某个位置呈现?
感谢专业人士
更新:以下是清除条件的代码
主要布局:
<html>
<body>
@if(someCondition){
@Html.RenderPartial("SamePartial")
@Html.RenderPartial("SamePartial")
@Html.RenderPartial("SamePartial")
}
</body>
</html>
这是部分内容:
<div>Blah Blah Blah</div>
@Scripts.Render("~/bundles/JusNeededInsidePartial")
@Styles.Render("~/Themes/styles/JusNeededInsidePartial")
部分呈现多次。我需要一种方法来只渲染一次束
答案 0 :(得分:2)
定义Razor部分:
@section MySpecialScripts {
@Scripts.Render("~/bundles/MySpecialScriptsBundle")
}
在您需要此类脚本的视图中,并将以下内容添加到主布局中:
@if (IsSectionDefined("MySpecialScripts")) {
RenderSection("MySpecialScripts")
}
答案 1 :(得分:2)
我对你在部分视图中放置捆绑包有点怀疑,就像你正在做的那样。
为了获得最佳效果,我建议将脚本放在页面底部(参考:http://developer.yahoo.com/blogs/ydn/high-performance-sites-rule-6-move-scripts-bottom-7200.html)
如果您的捆绑包包含样式表,那么您将把它们放在body
中,这仍然有效,但我喜欢整理它们以便它们全部在一起。
我通常会在结束_Layout.cshtml
标记之前将其添加到我的</head>
:
@RenderSection("Head", required: false)
然后,在我的View
中,我可以:
@Html.RenderPartial("SamePartial")
@Html.RenderPartial("SamePartial")
@Html.RenderPartial("SamePartial")
@section head{
@Scripts.Render("~/bundles/myBundle")
}
如果我想在另一个View
上做类似的事情:
@Html.RenderPartial("OtherPartial")
@Html.RenderPartial("OtherPartial")
@section head{
@Scripts.Render("~/bundles/myOtherBundle")
}
我知道这与你要求的有点不同,但我认为这个解决方案的灵活性是有价值的。
如果你动态加载东西,你总是可以在你的部分中添加一个简单的条件:
@section head{
@if(SomeCondition){
@Scripts.Render("~/bundles/modernizr")
}
}
答案 2 :(得分:1)
您可以自行检查JavaScript脚本:
在JavaScript中,您可以检查先前是否已定义某些内容,并且只有在未定义的情况下才进行定义。
例如:
if (typeof flag === 'undefined') {
// variable is undefined
flag = {};
// Here type the code that must happen only once
}
注意:标志名称是全局变量。为避免冲突,您需要“命名空间”,并为每个脚本文件使用特定名称,如下所示:
if (typeof myScripts === 'undefined') {
myScripts = {};
}
if (typeof myScripts.MySpecialScripts=== 'undefined')
{
myScripts.MySpecialScripts = '';
// Add the "MySpecialScripts.js" code here
}
然而,我会在部分之外渲染脚本包以确保它们可用。通过这种方式,您可以确保它只呈现一次并可供所有部分使用。
事实上,除非它是一个非常大的.js文件,为什么不把它包含在你的常规包中呢?
是的,我知道如果你在需要它们的视图中包含脚本,你觉得你的项目“组织得更好”,但这不是一个好主意:你必须控制它们是否已被包括在内,你是如果你愿意,可以将它们移到页面底部等等。
如果您仍想保留原始想法,可以使用client dependency framework。这不是你想要做的,但它是最好的解决方案。当您使用此框架时,you need to declare the dependencies of you components(视图)使用不同的方法,如下所示:
@{Html.RequiresJs("~/myscript.js");}
无论如何,正如我在评论中所写,这种解决方案的问题在于,如果你开始使用AJAX,没有一种方法可以确保你总是得到所需的脚本,并且它们在客户端可用什么时候需要它们。除非你使用我在这个答案中写的第一个客户端解决方案的一些变体(基于这个基本概念有更好的解决方案)。让我坚持认为:最好的解决方案是始终在客户端准备好一切(除非它是一个包含数百个大js文件的巨大项目)。请记住,js文件已加载一次,并缓存以供以后在浏览器中使用,因此下载一个大的.js文件并不是一个大问题。
请即使您认为需要服务器端解决方案,也不要丢弃客户端解决方案。请记住,即使你从服务器服务js,这是“客户端”代码,那么,为什么不为你的“客户端代码”问题使用“客户端解决方案”呢?
仍然是另一种解决方案: ypu可以使用PageData
在视图,布局和部分视图之间共享信息。当您需要在任何这些地方添加脚本时,请使用PageData
中的标记。如果该标志不存在,则渲染脚本,然后设置标志。如果该标志存在,请不要渲染脚本。这样,脚本将仅在第一次呈现。
if (PageData["JusNeededInsidePartial"] == null) // Check the flag
{
@Scripts.Render("~/bundles/JusNeededInsidePartial");
PageData["JusNeededInsidePartial"] = ""; // Set the flag
}
AJAX的问题仍然存在,因为如果你通过AJAX渲染局部,它将在客户端加载脚本,所有部分视图都由AJAX加载。