簡體   English   中英

在部分視圖中包含頁面底部的JavaScript

[英]Including JavaScript at bottom of page, from Partial Views

假設我在局部視圖中有一個javascript幻燈片放映...

_Slideshow.cshtml:

@{
    ViewBag.Title = "Slide Show";
}
<div id="slides">
</div>
<script src="js/slides.min.jquery.js"></script>
<script type="text/javascript">
$(function(){
    $('#slides').slides({
        // slide show configuration...
    });
});
</script>

但我想成為一名優秀的小型Web開發人員,並確保我的所有腳本都位於頁面底部。 所以我會讓我的* _Layout.cshtml *頁面看起來像這樣:

_Layout.cshtml:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/css/global.css")" rel="stylesheet" type="text/css" />
</head>
<body>
    <div id="wrapper">
    @RenderBody
    </div>
    <!-- Being a good little web developer, I include my scripts at the BOTTOM, yay!
    -->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
</body>
</html>

但是UH OH! 我現在該怎么做,因為我的幻燈片腳本最終超出了我的jQuery包含范圍?! 如果我想在每個頁面上播放幻燈片,這不會是什么大不了的事,但我只希望幻燈片放映部分視圖在某個頁面上呈現,並且......我希望我的腳本在底部! 該怎么辦?

您可以在布局頁面中為腳本定義一個部分,如下所示:

<body>
    <div id="wrapper">
    @RenderBody
    </div>
    <!-- Being a good little web developer, I include my scripts at the BOTTOM, yay!
    -->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
    @RenderSection("myScripts")
</body>

然后在您的頁面上定義該部分的內容:

@{
    ViewBag.Title = "Slide Show";
}
<div id="slides">
</div>
@section myScripts { //put your scripts here
    <script src="js/slides.min.jquery.js"></script>
    <script type="text/javascript">
    $(function(){
        $('#slides').slides({
            // slide show configuration...
        });
    });
    </script>
}

然后,當頁面呈現時,它將獲取您的部分中的所有內容並將其添加到應該放置在布局頁面上的位置(在本例中,在底部)。

注意 :如問題所示,已接受的解決方案不適 用於部分視圖

問題

{} declaration. 在正常流程中,您可以使用@section {}聲明從ActionResult上的父視圖內部定義特定部分的內容。 當該視圖最終插入其LayoutPage時,它可以調用RenderSection將這些內容放在頁面中的任何位置,允許您定義一些內聯JavaScript,可以在它依賴的任何核心庫之后在頁面底部呈現和解析像這樣:

布局>完整視圖

當您希望能夠在局部視圖中重用整個頁面視圖時,會出現問題。 也許您還想從另一個頁面內部將視圖重新用作窗口小部件或對話框。 在這種情況下,只要您在父視圖內部調用@Html.EditorFor@Html.Partial ,就會完整呈現完整的部分視圖,如下所示:

布局>父視圖>部分視圖

根據有關Razor語法的布局MSDN文檔

  • 視圖中定義的部分僅在其直接布局頁面中可用。
  • 無法從部分視圖,視圖組件或視圖系統的其他部分引用節。
  • 內容頁面中的正文和所有部分都必須由布局頁面呈現

在這種情況下,將定義到局部視圖中的腳本放到頁面底部變得很棘手。 根據文檔,您只能從布局視圖中調用RenderSection ,並且無法從局部視圖內部定義@section內容,因此所有內容都集中到同一區域,您的腳本將從中間呈現,解析和運行在您可能依賴的任何庫之后,您的HTML頁面而不是底部。

解決方案

有關將部分視圖中的部分注入頁面的多種方法的完整討論,我將從StackOverflow上的以下兩個問題開始:

其中的變化解決方案在對嵌套,排序,多腳本支持,不同內容類型,調用語法和可重用性的支持方面不同。 但無論你如何切片,幾乎任何解決方案都必須完成兩個基本任務:

  1. 逐步在任何頁面,部分視圖或模板中構建腳本對象到您的請求,可能會利用某種HtmlHelper擴展來實現可重用性。
  2. 將該腳本對象渲染到布局頁面上。 由於布局頁面實際上是最后渲染的,因此這只是將我們構建的對象發送到母版頁上。

這是Darin Dimitrov一個簡單實現

添加幫助程序擴展方法,它允許您將任意腳本對象構建到ViewContent.HttpContext.Items集合中,然后再獲取並呈現它們。

Utilities.cs

public static class HtmlExtensions
{
    public static MvcHtmlString Script(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
    {
        htmlHelper.ViewContext.HttpContext.Items["_script_" + Guid.NewGuid()] = template;
        return MvcHtmlString.Empty;
    }

    public static IHtmlString RenderScripts(this HtmlHelper htmlHelper)
    {
        foreach (object key in htmlHelper.ViewContext.HttpContext.Items.Keys)
        {
            if (key.ToString().StartsWith("_script_"))
            {
                var template = htmlHelper.ViewContext.HttpContext.Items[key] as Func<object, HelperResult>;
                if (template != null)
                {
                    htmlHelper.ViewContext.Writer.Write(template(null));
                }
            }
        }
        return MvcHtmlString.Empty;
    }
}

然后你可以在你的應用程序中使用這樣的

像這樣在Partial View中構建這樣的腳本對象,如下所示:

@Html.Script(
    
)

然后在LayoutPage中的任意位置渲染它們,如下所示:

@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
@Html.RenderScripts()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM