我在我的_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视图中注入一些内容。

我该怎么做呢?


当前回答

我们看待网络的方式有一个根本性的缺陷,尤其是在使用MVC的时候。缺陷在于JavaScript在某种程度上是视图的责任。视图是视图,JavaScript(行为或其他)是JavaScript。在Silverlight和WPF的MVVM模式中,我们面临着“视图优先”或“模型优先”的问题。在MVC中,我们应该总是尝试从模型的角度进行推理,而JavaScript在很多方面都是这个模型的一部分。

我建议使用AMD模式(我自己喜欢RequireJS)。在模块中分离你的JavaScript,定义你的功能,从JavaScript中钩子到你的html,而不是依赖于一个视图来加载JavaScript。这将清理您的代码,分离您的关注点,并使生活变得更简单。

其他回答

OP的目标是将内联脚本定义到他的Partial View中,我假设这个脚本仅特定于该Partial View,并将该块包含到他的脚本部分中。

我明白他想要局部视图是独立的。这个想法类似于使用Angular时的组件。

我的方法是将脚本原样保存在Partial View中。现在的问题是,当调用Partial View时,它可能会在所有其他脚本(通常被添加到布局页面的底部)之前执行脚本。在这种情况下,您只需让Partial View脚本等待其他脚本。有几种方法可以做到这一点。我之前用过的最简单的方法是在body上使用事件。

在我的布局中,我会在底部有这样的东西:

// global scripts
<script src="js/jquery.min.js"></script>
// view scripts
@RenderSection("scripts", false)
// then finally trigger partial view scripts
<script>
  (function(){
    document.querySelector('body').dispatchEvent(new Event('scriptsLoaded'));
  })();
</script>

然后在我的局部视图(在底部):

<script>
  (function(){
    document.querySelector('body').addEventListener('scriptsLoaded', function() {

      // .. do your thing here

    });
  })();
</script>

另一种解决方案是使用堆栈来推送所有脚本,并在最后调用每个脚本。其他解决方案,如前所述,是RequireJS/AMD模式,它也非常有效。

我有一个类似的问题,我有一个母版页如下:

@section Scripts {
<script>
    $(document).ready(function () {
        ...
    });
</script>
}

...

@Html.Partial("_Charts", Model)

但是部分视图依赖于脚本部分中的一些JavaScript。我通过将部分视图编码为JSON来解决这个问题,将其加载到JavaScript变量中,然后使用它来填充一个div,因此:

@{
    var partial = Html.Raw(Json.Encode(new { html = Html.Partial("_Charts", Model).ToString() }));
}

@section Scripts {
<script>
    $(document).ready(function () {
        ...
        var partial = @partial;
        $('#partial').html(partial.html);
    });
</script>
}

<div id="partial"></div>

我的解决方案是从布局页面加载脚本。然后在javacript中,检查局部视图中是否存在一个元素。如果元素存在,javascript就知道该部分已被包含。

$(document).ready(function () {
    var joinButton = $("#join");
    if (joinButton.length != 0) {
        // the partial is present
        // execute the relevant code
    }
});

好吧,我猜其他海报已经为你提供了一种直接在你的部分中包含@section的方法(通过使用第三方html助手)。

但是,我认为,如果你的脚本是紧密耦合到你的部分,只是把你的javascript直接放在一个内联<script>标签在你的部分,并完成它(只是要小心脚本复制,如果你打算使用部分不止一次在一个视图);

你可以选择使用你的文件夹/索引。CSHTML作为母版,然后添加节脚本。然后,在你的布局中,你有:

@RenderSection("scripts", required: false) 

和index.cshtml:

@section scripts{
     @Scripts.Render("~/Scripts/file.js")
}

它会在所有的partialviews上工作。这对我很有用