我在我的_Layout.cshtml中定义了这个部分

@RenderSection("Scripts", false)

我可以很容易地从视图中使用它:

@section Scripts { 
    @*Stuff comes here*@
}

我正在努力解决的问题是如何从局部视图将一些内容注入到这个部分中。

让我们假设这是我的视图页面:

@section Scripts { 

    <script>
        //code comes here
    </script>
}

<div>
    poo bar poo
</div>

<div>
  @Html.Partial("_myPartial")
</div>

我需要在脚本部分中从_myPartial partial视图中注入一些内容。

我该怎么做呢?


当前回答

有一种方法可以在局部视图中插入部分,尽管它并不漂亮。你需要从父视图中访问两个变量。由于部分视图的部分目的就是创建该section,因此需要这些变量是有意义的。

下面是在局部视图中插入一个section的样子:

@model KeyValuePair<WebPageBase, HtmlHelper>
@{
    Model.Key.DefineSection("SectionNameGoesHere", () =>
    {
        Model.Value.ViewContext.Writer.Write("Test");
    });
}

在页面中插入部分视图…

@Html.Partial(new KeyValuePair<WebPageBase, HtmlHelper>(this, Html))

您还可以使用此技术在任何类中以编程方式定义节的内容。

享受吧!

其他回答

如果你确实有合法的需要从一个部分运行一些js,这里是你可以做到的,jQuery是必需的:

<script type="text/javascript">        
    function scriptToExecute()
    {
        //The script you want to execute when page is ready.           
    }

    function runWhenReady()
    {
        if (window.$)
            scriptToExecute();                                   
        else
            setTimeout(runWhenReady, 100);
    }
    runWhenReady();
</script>

你可以使用这些扩展方法:(保存为PartialWithScript.cs)

namespace System.Web.Mvc.Html
{
    public static class PartialWithScript
    {
        public static void RenderPartialWithScript(this HtmlHelper htmlHelper, string partialViewName)
        {
            if (htmlHelper.ViewBag.ScriptPartials == null)
            {
                htmlHelper.ViewBag.ScriptPartials = new List<string>();
            }

            if (!htmlHelper.ViewBag.ScriptPartials.Contains(partialViewName))
            {
                htmlHelper.ViewBag.ScriptPartials.Add(partialViewName);
            }

            htmlHelper.ViewBag.ScriptPartialHtml = true;
            htmlHelper.RenderPartial(partialViewName);
        }

        public static void RenderPartialScripts(this HtmlHelper htmlHelper)
        {
            if (htmlHelper.ViewBag.ScriptPartials != null)
            {
                htmlHelper.ViewBag.ScriptPartialHtml = false;
                foreach (string partial in htmlHelper.ViewBag.ScriptPartials)
                {
                    htmlHelper.RenderPartial(partial);
                }
            }
        }
    }
}

像这样使用:

示例partial:(_MyPartial.cshtml) 把html放在if里,js放在else里。

@if (ViewBag.ScriptPartialHtml ?? true)
    <p>I has htmls</p>
}
else {
    <script type="text/javascript">
        alert('I has javascripts');
    </script>
}

在你的_Layout中。cshtml,或者任何你想要渲染的部分脚本的地方,放置以下(一次):它将只在当前页面的这个位置渲染所有部分的javascript。

@{ Html.RenderPartialScripts(); }

然后使用您的部分,只需这样做:它将只呈现该位置的html。

@{Html.RenderPartialWithScript("~/Views/MyController/_MyPartial.cshtml");}

我今天遇到了这个问题。我将添加一个工作区,使用<脚本延迟>,因为我没有看到其他答案提到它。

//on a JS file somewhere (i.e partial-view-caller.js)
(() => <your partial view script>)();

//in your Partial View
<script src="~/partial-view-caller.js" defer></script>

//you can actually just straight call your partial view script living in an external file - I just prefer having an initialization method :)

上面的代码摘自我关于这个问题的一篇文章。

我解决这个完全不同的路线(因为我很着急,不想实现一个新的HtmlHelper):

我用一个大的if-else语句包装了我的Partial View:

@if ((bool)ViewData["ShouldRenderScripts"] == true){
// Scripts
}else{
// Html
}

然后,我用自定义ViewData调用了两次Partial:

@Html.Partial("MyPartialView", Model, 
    new ViewDataDictionary { { "ShouldRenderScripts", false } })

@section scripts{
    @Html.Partial("MyPartialView", Model, 
        new ViewDataDictionary { { "ShouldRenderScripts", true } })
}

我用这个方法解决了类似的问题:

@section ***{
@RenderSection("****", required: false)
}

我想这是一种很好的注射方式。