使用 Twitter Bootstrap 在 ASP.NET MVC 中调用模式对话框的最佳方法是啥?

Posted

技术标签:

【中文标题】使用 Twitter Bootstrap 在 ASP.NET MVC 中调用模式对话框的最佳方法是啥?【英文标题】:What's the best way to call a modal dialog in ASP.NET MVC using Twitter Bootstrap?使用 Twitter Bootstrap 在 ASP.NET MVC 中调用模式对话框的最佳方法是什么? 【发布时间】:2011-12-26 23:25:36 【问题描述】:

我目前在一个新项目中使用Twitter's Bootstrap toolkit,我对在 ASP.NET MVC3 中使用模式对话框的最佳方式有疑问。

最好的做法是让 Partial 包含模态标记,然后使用 javascript 将其呈现到页面上,还是有更好的方法?

【问题讨论】:

【参考方案1】:

这是我的小教程,它演示了 Twitter 的 Bootstrap (2.x) 模式对话框,该对话框适用于 ASP.Net MVC 4 中的表单和部分。

要下载类似项目,但针对 MVC 5.1 和 Bootstrap 3.1.1,请visit this site。

从一个空的 MVC 4 Internet 模板开始。

使用 NuGet 添加对 Bootstrap 的引用

在 App_Start/BundleConfig.cs 添加以下行:

bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include("~/Scripts/bootstrap.js"));
bundles.Add(new StyleBundle("~/Content/bootstrap").Include(
                    "~/Content/bootstrap.css",
                    "~/Content/bootstrap-responsive.css"));

在 Views/Shared/_Layout.cshtml 中 修改 @styles.Render 行,使其看起来像:

@Styles.Render("~/Content/css", "~/Content/themes/base/css",  "~/Content/bootstrap")

和@Scripts.Render 行:

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

到目前为止,我们已经准备好使用 MVC 4 的 Bootstrap,所以让我们在 /Models 文件夹中添加一个简单的模型类 MyViewModel.cs:

using System.ComponentModel.DataAnnotations;

namespace MvcApplication1.Models

    public class MyViewModel
    
        public string Foo  get; set; 

        [Required(ErrorMessage = "The bar is absolutely required")]
        public string Bar  get; set; 
    

在 HomeController 中添加以下行:

using MvcApplication1.Models;
//...

    public ActionResult Create()
    
        return PartialView("_Create");
    

    [HttpPost]
    public ActionResult Create(MyViewModel model)
    
        if (ModelState.IsValid)
        
            try
            
                SaveChanges(model);
                return Json(new  success = true );
            
            catch (Exception e)
            
                ModelState.AddModelError("", e.Message);
            

        
        //Something bad happened
        return PartialView("_Create", model);
    


    static void SaveChanges(MyViewModel model)
    
        // Uncommment next line to demonstrate errors in modal
        //throw new Exception("Error test");
    

在 Views/Home 文件夹中创建新的 Partial View 并将其命名为 _Create.cshtml:

@using MvcApplication1.Models
@model MyViewModel

<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 id="myModalLabel">Create Foo Bar</h3>
</div>

@using (Html.BeginForm("Create", "Home", FormMethod.Post, new  @class = "modal-form" ))

@Html.ValidationSummary()

<div  class="modal-body">
    <div>
        @Html.LabelFor(x => x.Foo)
        @Html.EditorFor(x => x.Foo)
        @Html.ValidationMessageFor(x => x.Foo)
    </div>
    <div>
        @Html.LabelFor(x => x.Bar)
        @Html.EditorFor(x => x.Bar)
        @Html.ValidationMessageFor(x => x.Bar)
    </div>
</div>

<div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Undo</button>
    <button class="btn btn-primary" type="submit">Save</button>
</div>


在 Home/Index.cshtml 中删除模板中的默认内容并将其替换为以下内容:

@
    ViewBag.Title = "Home Page";


<br />
<br />
<br />

@Html.ActionLink("Create", "Create", null, null, new  id = "btnCreate", @class = "btn btn-small btn-info" )

<div id='dialogDiv' class='modal hide fade in'>
    <div id='dialogContent'></div>
</div>

@section Scripts 
@Scripts.Render("~/bundles/jqueryval")

<script type="text/javascript">
    $(function () 

        //Optional: turn the chache off
        $.ajaxSetup( cache: false );

        $('#btnCreate').click(function () 
            $('#dialogContent').load(this.href, function () 
                $('#dialogDiv').modal(
                    backdrop: 'static',
                    keyboard: true
                , 'show');
                bindForm(this);
            );
            return false;
        );
    );

    function bindForm(dialog) 
        $('form', dialog).submit(function () 
            $.ajax(
                url: this.action,
                type: this.method,
                data: $(this).serialize(),
                success: function (result) 
                    if (result.success) 
                        $('#dialogDiv').modal('hide');
                        // Refresh:
                        // location.reload();
                     else 
                        $('#dialogContent').html(result);
                        bindForm();
                    
                
            );
            return false;
        );
    

</script>

如果您运行您的应用程序,点击主页上的“创建”按钮后会出现一个漂亮的 Bootstrap 模式。

尝试取消注释 HomeController.cs 中的 SaveChanges() //throw 行,以证明您的控制器处理的错误将正确显示在对话框中。

我希望我的示例能够阐明在 MVC 应用程序中合并 Bootstrap 和创建模式的整个过程。

【讨论】:

zjerry,我使用了这种方法,效果很好。有没有一种简单的方法可以在同一页面上显示多个模式。基本上有一个模型列表,每个模型都有不同的 id。 感谢您的回答。但是,我是唯一需要 a) 添加 $.validator.unobtrusive.parse(form); 的人吗? if (form.valid()) ... 在表单中提交(以确保在客户端完成验证)和 b)在服务器端异常/模型验证问题之后,无法再次成功绑定表单,以便它会触发 ajax 帖子而不是标准帖子? 我想知道 POST Create 方法的断点是否应该命中。它不在我的机器上 发现问题。如果按“保存更改”时未调用您的“HTTPPOST”操作,请查看我的错误***.com/a/17472920/351708 我准备了另一个示例,更新后可与 MVC5 和 Bootstrap 3.1.1 一起使用。 Here you can download 项目(C# VS2013)。【参考方案2】:

很好的例子,我不得不对 MVC 5 和 Bootstrap 3.3.7 稍作修改,我将目标 div 标签更改为以下内容,否则我只会得到灰色背景并且没有模式对话框。希望这可以帮助某人。

<div id='dialogDiv' class='modal fade' tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div id='dialogContent'></div>
        </div>
    </div>
</div>

【讨论】:

感谢@Kevin Able,我还必须使用这个修改来让它为我工作。任何想法为什么或仅仅是由于更高版本的引导程序,即 3.3.7?【参考方案3】:

感谢@zjerry 解决方案很棒,但是 jQuery 验证不起作用,为了修复你需要更改函数 bindForm 如下:

function bindForm(dialog) 
        $.validator.unobtrusive.parse('form');
        $('form', dialog).submit(function () 
            $.ajax(
                url: this.action,
                type: this.method,
                data: $(this).serialize(),
                success: function (result) 
                    if (result.success) 
                        $('#dialogDiv').modal('hide');
                        // Refresh:
                        // location.reload();
                     else 
                        $('#dialogContent').html(result);
                        bindForm();
                    
                
            );
            return false;
        );
    

注意函数的第一行,因为表单是在初始化 jQuery 验证之后加载的。

非常感谢

【讨论】:

【参考方案4】:

这真的取决于你的设计,但你应该有一个模态的模板。

例如,在单个 Web 应用程序上,您应该有一个模板,每次都可以创建一个新实例。

通常在普通网站上,您会希望将此模板存储在 js 创建函数中,这样您就不必每次都通过 http 将文件发送给用户,并且他们可以将其缓存。

【讨论】:

这就是我正在做的,但我没有看到一种简单的方法来即时更新此模板中的信息(不使用 angular/knockout)

以上是关于使用 Twitter Bootstrap 在 ASP.NET MVC 中调用模式对话框的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Bootstrap 3 在 Twitter Typeahead 上的 CSS 问题

我啥时候应该在 Twitter Bootstrap 中使用容器和行?

Twitter-bootstrap 模式未在页面加载时显示(灰屏)

在 CSS 中使用 Twitter Bootstrap 字形图标

如何在 twitter-bootstrap-3 模态框中使用复选框

如何使用 Twitter Bootstrap 自动关闭警报