有没有办法确定ASP.Net MVC Bundle之前是否呈现?

时间:2014-01-10 10:55:56

标签: asp.net asp.net-mvc asp.net-mvc-4 asp.net-mvc-5

情况如下:

在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")

部分呈现多次。我需要一种方法来只渲染一次束

3 个答案:

答案 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加载。