部分视图中的Bootstrap模态的DOM放置

时间:2015-12-29 18:46:17

标签: asp.net-mvc twitter-bootstrap-3 asp.net-mvc-partialview

我有一个触发模态的按钮元素。这段代码是可重用的,需要出现在许多不同的视图中。

<button class="btn btn-default" type="button" data-toggle="modal" data-target="#modalAcctToggle">
    Toggle Accounts
</button>

<div id="modalAcctToggle" tabindex="-1" class="modal fade">
    <div class="modal-dialog modal-sm">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
                <h4 class="modal-title">Available Accounts</h4>
            </div>
            <div class="modal-body">
                [contents not relevant]
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

非常简单明了。将所有内容放在局部视图中,并根据需要使用@ Html.Partial(“_ accountToggler”)

进行渲染

但是,Bootstrap文档鼓励将模态置于页面之外:

http://getbootstrap.com/javascript/#modals

  

模态标记位置始终尝试将模式的HTML代码放在文档的顶级位置以避免其他组件   影响模态的外观和/或功能。

我的直接想法是使用Razor部分。

<button data-target="#modalAcctToggle" etc... />
@section modals {
    <div id="modalAcctToggle" etc... />
}

将所有模态包装在一个部分中,然后在布局中使用@RenderSection(“modals”),并且模式将在DOM中的安全位置发出。

不幸的是,Razor部分在部分视图中不起作用!这显然是设计的,但它意味着限制脚本在部分中的使用。

我发现很多其他问题来自人们试图解决部分内容缺乏部分的问题,但他们专注于处理脚本。在那里找到的解决方案基本上包括滚动你自己的Razor部分,或专门用于处理脚本(如捆绑)。当我的使用不是上述限制的目标时,必须努力重新发明Razor部分来破解故意限制,这似乎是荒谬的。

如何才能最好地将模态 HTML 放到另一个位置?

更新:正如对答案的评论中所讨论的,这个问题基于两个基本的误解。

1)Bootstrap模式可以位于HTML的其余部分而不会出现问题。你只需要小心,不要继承它不应该继承的任何CSS。

2)章节不是累积的。所以即使我可以在部分视图中使用部分,它也不会按照我想要的方式工作。使用相同部分的多个部分将相互覆盖。这可能是因为设计部分不能在部分中起作用的真正原因。

1 个答案:

答案 0 :(得分:2)

TL; DR; 这里的关键点是布局视图中的定义部分;它们大致相当于您在WebForms项目中找到的ContentPlaceholder控件。然后将它们用于通常与您的各种操作相对应的“完整”视图中。如果您尚未阅读,我会说Scott Gu's intro to sections有一个很好的解释。

如果我们假设您有这个局部视图,我将其称为_Modal.cshtml

<button class="btn btn-default" type="button" data-toggle="modal" data-target="#modalAcctToggle">
    Toggle Accounts
</button>

<div id="modalAcctToggle" tabindex="-1" class="modal fade">
    <div class="modal-dialog modal-sm">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
                <h4 class="modal-title">Available Accounts</h4>
            </div>
            <div class="modal-body">
                [contents not relevant]
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

你的布局类似于

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

</head>
<body>
    @RenderSection("modals", required: false)

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
        </footer>
    </div>

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

    @RenderSection("scripts", required: false)
</body>
</html>

可以做这样的事情,比如Index.cshtml

@section modals
{
    @Html.Partial("_Modal")
}

它将在正确的位置发出正确的标记。然后,您需要将任何交互逻辑直接放在父视图中,或使用scripts部分(在父视图中)。