【问题标题】:How to render JavaScript into MasterLayout section from partial view?如何从局部视图将 JavaScript 渲染到 MasterLayout 部分?
【发布时间】:2011-08-24 07:13:27
【问题描述】:

鉴于 MVC3 和 Razor 引擎,我得到了

_MasterLayout.cshtml

@RenderSection("JavaScript", required: false)
..
..
@RenderBody()
..

View.cshtml,在 _ViewStart.cshtml 中定义了 _MasterLayout.cshtml

..
@Html.RenderAction("PartialView", "PartialController")
..

PartialView.cshtml

..
@section JavaScript
{
........
}
..

如何确保部分视图中的 JavaScript 最终出现在主布局部分?

编辑

上述方案不起作用,因为局部视图没有定义主布局。另一方面,视图确实具有定义了 RenderSection 的布局。如果我将部分 JavaScript 从 Partial View 移动到 View,Razor 知道将其渲染到哪里。但是,由于局部视图没有布局,它不知道如何处理部分 JavaScript,因此不会在任何地方呈现它。

【问题讨论】:

  • 我不明白这个问题 - 这不起作用吗?如果不是,为什么不呢?你有错误吗? RenderSection() 是否被替换为空?
  • @Danny Tuppeny - 我在问题中添加了 EDIT,让我知道这是否有意义。谢谢。
  • 几周前我问过类似的问题:stackoverflow.com/questions/5355427/…

标签: asp.net-mvc-3 c#-4.0 razor


【解决方案1】:

我不相信部分视图可以设置要在布局页面中使用的部分:(

似乎没有很好的解决方案 - 您可以包含两个部分(一个用于脚本,一个用于内容):

<script stuff>
@Html.RenderAction("PartialViewScripts", "PartialController")
</script stuff>
<body stuff>
@Html.RenderAction("PartialView", "PartialController")
</body stuff>

【讨论】:

  • 会在 View.cshtml 中吗?
  • 没错,没错。而且您需要在 PartialController 上使用两个操作 - 一个用于视图,一个用于脚本。这不是特别好,但我现在想不出更好的方法:(
  • 是的,我在等待答案时正在考虑类似的方法。基本上,我在视图中有一个条件。如果是真的,我会渲染部分内容。我只是要将 js 部分添加到该条件的内部,而不会仅为 js 制作第二个局部视图。谢谢你的回答。
【解决方案2】:

我创建了一组扩展方法来将脚本块(或任何东西)从部分渲染到主布局。

public static class ViewPageExtensions
{  
 private const string SCRIPTBLOCK_BUILDER = "ScriptBlockBuilder";

    public static MvcHtmlString ScriptBlock(
        this WebViewPage webPage,
        Func<dynamic, HelperResult> template)
    {
        if (!webPage.IsAjax)
        {
            var scriptBuilder = webPage.Context.Items[SCRIPTBLOCK_BUILDER] 
                                as StringBuilder ?? new StringBuilder();

            scriptBuilder.Append(template(null).ToHtmlString());

            webPage.Context.Items[SCRIPTBLOCK_BUILDER] = scriptBuilder;

            return new MvcHtmlString(string.Empty);
        }
        return new MvcHtmlString(template(null).ToHtmlString());
    }

    public static MvcHtmlString WriteScriptBlocks(this WebViewPage webPage)
    {
        var scriptBuilder = webPage.Context.Items[SCRIPTBLOCK_BUILDER] 
                            as StringBuilder ?? new StringBuilder();

        return new MvcHtmlString(scriptBuilder.ToString());
    }
}

那么就可以这样使用了:

@this.ScriptBlock(
@<script  type='text/javascript'>
    $(document).ready(function () {
        notify('@message', '@Model.Type.ToString()',                    
               '@Model.Type.ToString().ToLower()');
    });
</script>)

然后在主布局中渲染:

@this.WriteScriptBlocks()

在此处查看全文:A Script-Block Templated Delegate for Inline-Scripts in Razor Partials

【讨论】:

  • 一个好的答案的标志不仅仅是链接到您自己承认“消失”了一段时间的文章。为什么不总结帖子并包含代码示例,这样如果链接再次失败,未来的用户就不会被蒙在鼓里。此外,在发布多个问题的复制和粘贴样板/逐字答案时要小心,这些往往会被社区标记为“垃圾邮件”。
  • 感谢您的反馈。我会添加你提到的细节。
  • 我真的很喜欢你的想法。谢谢!
  • 如何管理渲染顺序?我的意思是,如果其中一些ScriptBlock 调用发生在WriteScriptBlocks 调用之后呢?
  • 我重读了你的实现,它简单而精彩,这应该是默认的 mvc 实现。
【解决方案3】:

这对我有用,允许我将 javascript 和 html 放在同一文件中以进行部分视图,以便于阅读

在使用名为“_MyPartialView.cshtml”的局部视图的视图中

<div>
    @Html.Partial("_MyPartialView",< model for partial view>,
            new ViewDataDictionary { { "Region", "HTMLSection" } } })
</div>

@section scripts{

    @Html.Partial("_MyPartialView",<model for partial view>, 
                  new ViewDataDictionary { { "Region", "ScriptSection" } })

 }

在部分视图文件中

@model SomeType

@{
    var region = ViewData["Region"] as string;
}

@if (region == "HTMLSection")
{


}

@if (region == "ScriptSection")
{
        <script type="text/javascript">
    </script">
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 2016-02-28
    相关资源
    最近更新 更多