C# 如果在页面底部呈现绑定脚本,如何使用动态JQuery脚本定义局部视图?

C# 如果在页面底部呈现绑定脚本,如何使用动态JQuery脚本定义局部视图?,c#,jquery,asp.net-mvc,razor,asp.net-mvc-partialview,C#,Jquery,Asp.net Mvc,Razor,Asp.net Mvc Partialview,我有一个使用MVC4和Razor视图的web应用程序,它们利用了大量JQuery和其他插件脚本 为了加快视图的渲染速度,我认为一般来说,在主体底部渲染脚本是一种很好的做法,因此布局(非常整合)如下所示: <body> @RenderBody() @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/other") @RenderSection( "Scripts", false

我有一个使用MVC4和Razor视图的web应用程序,它们利用了大量JQuery和其他插件脚本

为了加快视图的渲染速度,我认为一般来说,在主体底部渲染脚本是一种很好的做法,因此布局(非常整合)如下所示:

<body>
    @RenderBody()

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

    @RenderSection( "Scripts", false )
</body>
此部分(_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函数,因为JQuery库在每个集合项的_MyPartial脚本之前未加载。在chrome调试器中运行时显示
$notdefined
,这证实了这一点

我可以做一些非常难看的事情,比如为调用分部的所有视图复制脚本部分中的每个foreach语句,然后让父视图生成脚本。但是,这实际上扼杀了局部视图的可重用性


有没有办法让Razor局部视图脚本延迟渲染(例如在“父脚本”部分中),或者有其他方法解决此问题?

不幸的是,局部视图中不支持部分。一种可能是编写自定义助手,如我在本文中所述:

这将允许您在文档末尾调用占位符帮助器,它将呈现已在部分中注册的所有脚本

话虽如此,将部分用户需要的客户端功能公开为jQuery插件通常是一个更好的主意。然后,在一些DOM元素上调用此插件非常容易:

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

这样,您就不再需要在partials中执行任何
$(“#@(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.RegisteredRawScripts()

我会在页面顶部呈现必要的脚本,然后在底部呈现其余脚本。我希望至少呈现库文件,即在顶部呈现jquery。如果我要在应用程序中使用它们,我会考虑根据每个视图的特定需要在顶部渲染一些脚本。可能会有点乱。:-)谢谢Darin,这看起来很有希望,我今晚回家后会仔细看看。
@Html.RegisterRawScript(script);  // where script is your raw script as a string
@Html.RegisteredRawScripts()