简单的ASP.NET MVC CRUD在JavaScript UI对话框中查看打开/关闭

mar*_*are 10 asp.net-mvc jquery jquery-ui modal-dialog post-redirect-get

我有各种简单的ASP.NET MVC视图用于CRUD操作,它们可以作为一个简单的网页自行运行.我现在将它们集成到网站本身(进入内容)并拥有像"创建新帖子"这样的链接,它会激活所选Lightbox克隆中的视图(不知道哪一个,可能是Colorbox或Thickbox但是没关系).

我想要实现的是视图本身以某种方式检测到它是在JavaScript UI对话框中打开的,这样Form动作(最常见的是使用简单的Submit按钮的POST)将使用一个逻辑来渲染,该逻辑将关闭UI对话框.行动已经完成.

视图的工作方式现在是POST/Redirect/GET.在Web浏览器中直接通过URL打开时,视图仍应支持这种简单模式,但在通过JavaScript对话框打开时应该呈现一些额外的逻辑.

希望你理解我的问题.任何帮助赞赏

Joh*_*ell 11

你好运,我做到了!

所以你需要的第一件事就是一个新的ViewEngine来处理一个页面而没有所有正常的页眉/页脚内容会妨碍你的模态窗口.最简单的方法是为模态窗口使用一个基本为空的母版页.您希望主页切换逻辑不受影响并且在自定义ViewEngine中,因为否则每个控制器方法都必须在检测到IsAjaxRequest()的地方都有if()else().我喜欢干燥,撒哈拉干燥.

通过这种技术,我还可以非常优雅地降级.我的网站功能完全没有javascript.链接很好,表单工作,零代码更改从"模态感知网站"到普通的旧HTML表单提交.

我所做的就是将默认引擎子类化并添加一些MasterPage选择位:

视图引擎:

public class ModalViewEngine : VirtualPathProviderViewEngine 
{
    public ModalViewEngine()
    {                
     /* {0} = view name or master page name 
      * {1} = controller name      */  

     MasterLocationFormats = new[] {  
         "~/Views/Shared/{0}.master"  
     };  

     ViewLocationFormats = new[] {  
         "~/Views/{1}/{0}.aspx",  
         "~/Views/Shared/{0}.aspx"
     };  

     PartialViewLocationFormats = new[] {  
         "~/Views/{1}/{0}.ascx",               
        }; 
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        throw new NotImplementedException();
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {

        return new WebFormView(viewPath, masterPath );
    }

    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
    {
        //you might have to customize this bit
        if (controllerContext.HttpContext.Request.IsAjaxRequest())
            return base.FindView(controllerContext, viewName, "Modal", useCache);

        return base.FindView(controllerContext, viewName, "Site", useCache);
    }

    protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
    {
        return base.FileExists(controllerContext, virtualPath);
    }        
}
Run Code Online (Sandbox Code Playgroud)

所以我的Modal.Master页面非常简单.我只有一个div包装器,所以我知道什么时候在模态窗口内呈现.当需要仅在元素处于"模态模式"时使用jquery选择某些元素时,这将非常有用.

Modal.Master

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<div id="modalcontent"><asp:ContentPlaceHolder ID="MainContent" runat="server" /></div>
Run Code Online (Sandbox Code Playgroud)

下一步是创建表单.我使用默认属性name = input name,这样我就可以轻松地对bind进行建模并保持简单.表格没什么特别之处.我看起来就像你正常做的那样.(注意我在我的代码中使用了MVC 2和EditorFor(),但这不重要)这是我的最终HTML:

HTML输出

<div id="modalcontent">
    <h2>EditFood</h2>
    <div id="form">
        <form method="post" action="/edit/food?Length=8">
            <input id="CommonName" class="text-box single-line" type="text" value="" name="CommonName"/>
            <input class="button" type="submit" value="Edit Food"/>
        </form>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

除了模型绑定之外,您还可以使用Jquery.Form插件,使用最少的代码将无缝且简单的ajax功能分层到您的应用程序中.现在我选择ColorBox作为我的模态窗口脚本纯粹是因为我想要Facebookesque透明角落,我喜欢作者添加的可扩展性点.

现在将这些脚本组合起来,你会得到一个非常好的组合,这使得这个技术在javascript中很容易实现.我必须添加的唯一的JavaScript是(在document.ready内):

使用Javascript/jQuery的

    $("a.edit").colorbox({ maxWidth: "800px", opacity: 0.4, initialWidth: 50, initialHeight: 50 });

    $().bind('cbox_complete', function () {
        $("#form form").ajaxForm(function () { $.fn.colorbox.close() });
    });
Run Code Online (Sandbox Code Playgroud)

在这里,我告诉ColorBox为我的编辑链接(编辑食物)打开一个模态窗口.然后绑定转到colorbox的完整事件,用一个成功的回调来连接你的ajaxform东西,告诉ColorBox关闭模态窗口.而已.

这段代码都是作为概念证明完成的,这也就是为什么视图引擎非常精简而且没有验证或其他标准形式的bling.ColorBox和JQuery.Form具有大量的可扩展性支持,因此定制它应该很容易.

请注意,这一切都是在MVC 2中完成的,但这里只是我的控制器代码,只是为了表明这是多么容易.请记住,我的概念验证目标是让模态窗口以这样的方式工作,除了设置一些基本的基础结构之外,我不需要进行任何代码更改.

    [UrlRoute(Path="edit/food")]
    public ActionResult EditFood()
    {            
        return View(new Food());
    }

    [HttpPost][UrlRoute(Path = "edit/food")]
    public ActionResult EditFood(Food food)
    {          
        return View(food);
    }
Run Code Online (Sandbox Code Playgroud)