在MVC 4.0中使用部分视图中的节

时间:2012-09-14 18:27:38

标签: asp.net .net asp.net-mvc razor asp.net-mvc-4

当我遇到需要在特定元素上初始化jQuery ui的情况时,我想在部分视图中包含脚本。它确实属于部分页面而不是包含页面或布局。

据说在MVC 4中有一种方法可以做到,但我似乎无法找到任何信息。

2 个答案:

答案 0 :(得分:6)

我也有类似的问题。希望这可以帮助。 我们希望有一个视图,其中包含一个显示某些数据的公共标题部分,以及当我们单击页面中的链接时应该动态更改的另一个部分。 (类似于标签的东西) 由于我们不想多次重新加载标题部分,因此我们决定使用容器视图和占位符div,当我们单击ajax链接时,它将用于动态加载局部视图。 但是,加载到占位符的部分视图有很多javascript代码,我们无法将不同部分视图使用的所有代码都包含在单个javascript文件中,并从容器视图中引用它,因为存在一些冲突的函数。 引入命名空间来修复该问题也不是非常有效的方法,因为所有的javascript逻辑仍然会被不必要地加载。 做一些谷歌搜索让我意识到在局部视图中有一个脚本部分是行不通的。我尝试使用@RenderSection(“partialScripts”,required:false)在视图中定义一个部分失败,因为RenderSection仅适用于布局视图。 以下是我采取的克服这个问题的方法。 在布局视图中定义的脚本部分可以包含任何有效标记。所以我决定有一个div,它将帮助我在容器视图的脚本部分内动态加载脚本。动作链接的OnSuccess事件处理程序用于动态附加脚本。 这是我的容器视图的代码。

<ul>
    <li>
        @Ajax.ActionLink("Partial One", "PartialOne", ajaxOptions: new AjaxOptions
                     {
                         HttpMethod = "Get",
                         InsertionMode = InsertionMode.Replace,
                         UpdateTargetId = "container",
                         OnSuccess = "loadScriptsDynamically('PartialOne')"
                     })
    </li>
    <li>
        @Ajax.ActionLink("Partial Two", "PartialTwo", ajaxOptions: new AjaxOptions
                     {
                         HttpMethod = "Get",
                         InsertionMode = InsertionMode.Replace,
                         UpdateTargetId = "container",
                         OnSuccess = "loadScriptsDynamically('PartialTwo')"
                     })
    </li>
</ul>

<div id="container">
</div>

@section scripts
{
    <script src="@Url.Content("~/Scripts/app/Container.js")"></script>
    <div id="dynamicScripts"
         data-partial-one="@Url.Content("~/Scripts/App/PartialOne.js")"
         data-partial-two="@Url.Content("~/Scripts/App/PartialTwo.js")">
    </div>
}

来自控制器类的代码

    public PartialViewResult PartialOne()
    {
        return PartialView("_PartialOne");
    }

    public PartialViewResult PartialTwo()
    {
        return PartialView("_PartialTwo");
    }

Container.js文件包含将为不同的部分视图动态加载必要脚本的逻辑。

function loadScriptsDynamically(name) {
    var script = document.createElement('script');
    var dynamicScriptsDiv = document.getElementById('dynamicScripts');
    var dynamicScriptDivJQuery = $('#dynamicScripts');
    dynamicScriptDivJQuery.empty();
    if (name === 'PartialOne') {
        script.src = dynamicScriptDivJQuery.data('partial-one');
        dynamicScriptsDiv.appendChild(script);
    } else if (name === 'PartialTwo'){
        script.src = dynamicScriptDivJQuery.data('partial-two');
        dynamicScriptsDiv.appendChild(script);
    }
}

由于某些限制,我们无法使用jQuery将脚本元素附加到div。但我们可以使用一些老式的JavaScript代码来创建一个脚本元素并将其附加到dynamicScriptsDiv。请注意,我正在访问我以前附加到dynamicScriptsDivusing的脚本路径使用一些数据属性,因为我们的MVC应用程序在IIS服务器中运行,我们不想对它们进行硬编码。

动态加载脚本后附加到事件是我们的下一个挑战。通过使用立即调用函数,我能够使用以下代码注册我所有的事件绑定代码和任何初始化逻辑。

(function initPartialOne() {
    $('#myButton').click(function() {
        setLabelText();
    });
})();

function setLabelText() {
    $('#myLabel').text('One was clicked');
}

最后是我的部分观点之一的代码。

<label id="myLabel">[Message]</label>
<input type="button" id="myButton" value="Click me partial one"/>

答案 1 :(得分:1)

这在ASP.NET MVC 3 See second comment in this post)中是不可能的。节只能用于(主)视图,而不能用于部分视图。

我目前无法根据MVC版本4找到任何资源,但Visual Studio中的简短测试也无法用于MVC 4,除非您在该部分内部渲染整个局部视图。

然而,我不建议做这样的事情。我过去一直在体验缓存问题,例如使用donut-caching部分视图。缓存部分视图导致代码未被执行并导致尚未呈现必要的javascript代码。所以我建议在局部视图中放置部分视图所需的一切或(甚至更好)考虑一个清晰的设计,并将所有的javascript代码放在一个为整个页面加载一次的缩小javascript文件中(然后缓存在浏览器的缓存中。)