簡體   English   中英

如果在頁面底部呈現捆綁腳本,如何使用動態JQuery腳本定義部分視圖?

[英]How can I define partial views with dynamic JQuery scripts if bundled scripts are rendered at the bottom of the page?

我有一個使用MVC4和Razor視圖的Web應用程序,它們使用了大量的JQuery和其他插件腳本。

為了加快視圖的渲染速度,我相信一般來說,最好將腳本渲染到正文的底部,因此布局(大大合並)如下所示:

<body>
    @RenderBody()

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/other")

    @RenderSection( "Scripts", false )
</body>

Scripts部分允許特定視圖添加其他JQuery函數,並且保證它們在JQuery庫之后呈現。 到現在為止還挺好。

現在考慮視圖中的以下片段,該片段為集合中的每個項目呈現部分:

@foreach (var item in Model.Items)
{
    Html.RenderPartial("_MyPartial", item);
}

這個部分(_MyPartial)需要根據集合項詳細信息(如下面的代碼段)為控件呈現JQuery:

$(function () {
    $("#@(Model.Id)").click(function () {
        // do something when control on partial with id Model.Id is clicked
        alert("I've been clicked!");
    });
});

部分視圖JQuery函數不會被執行,因為在每個集合項的_MyPartial腳本之前沒有加載JQuery庫。 在chrome調試器中運行顯示$ not defined ,這證實了這一點。

我可以做一些非常丑陋的事情,例如在腳本部分復制每個foreach語句,用於調用partial的所有視圖,然后讓父視圖生成腳本。 但是,這實際上會破壞局部視圖的可重用性。

有沒有辦法讓Razor部分視圖腳本延遲渲染(例如在父腳本部分中),或者是針對此問題的不同方法?

不幸的是,部分視圖中不支持部分。 一種可能性是編寫自定義幫助程序,如本文所述: https//stackoverflow.com/a/9663249/29407

這將允許您在文檔末尾調用占位符助手,該助手將呈現已在partials中注冊的所有腳本。

這就是說,通常更好的方法是將您部分需要的客戶端功能公開為jQuery插件。 然后在一些DOM元素上調用此插件非常容易:

$('.someElement').somePlugin();

這樣你就不再需要在你的部分中做任何$("#@(Model.Id)") 部分通常不應包含任何腳本。

作為參考,我使用了Darin的解決方案,並且還針對我需要注冊不在文件中的原始腳本的情況進行了擴展。 其他方法是:

public static class HtmlExtensions
{
    public static IHtmlString RegisteredRawScripts(this HtmlHelper htmlHelper)
    {
        var ctx = htmlHelper.ViewContext.HttpContext;
        var registeredScripts = ctx.Items["_rawscripts_"] as Stack<string>;
        if (registeredScripts == null || registeredScripts.Count < 1)
        {
            return null;
        }
        var sb = new StringBuilder();
        foreach (var script in registeredScripts)
        {
            sb.AppendLine("\r\n" + script);
        }
        return new HtmlString(sb.ToString());
    }

    public static void RegisterRawScript(this HtmlHelper htmlHelper, string script)
    {
        var ctx = htmlHelper.ViewContext.HttpContext;
        var registeredScripts = ctx.Items["_rawscripts_"] as Stack<string>;
        if (registeredScripts == null)
        {
            registeredScripts = new Stack<string>();
            ctx.Items["_rawscripts_"] = registeredScripts;
        }
        if (!registeredScripts.Contains(script))
        {
            registeredScripts.Push(script);
        }
    }
}

在你的部分,你做的事情如下:

@Html.RegisterRawScript(script);  // where script is your raw script as a string

在您的布局中,您注冊了原始腳本:

@Html.RegisteredRawScripts()

暫無
暫無

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

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