【问题标题】: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 将其呈现到页面上,还是有更好的方法?

【问题讨论】:

    标签: c# jquery asp.net-mvc-3 twitter-bootstrap


    【解决方案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”操作,请查看我的错误stackoverflow.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)
      猜你喜欢
      • 1970-01-01
      • 2010-11-30
      • 2011-11-10
      • 2010-09-13
      • 1970-01-01
      • 2012-04-08
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多