简单的 ASP.NET MVC CRUD 视图在 JavaScript UI 对话框中打开/关闭 [英] Simple ASP.NET MVC CRUD views opening/closing in JavaScript UI dialog

查看:21
本文介绍了简单的 ASP.NET MVC CRUD 视图在 JavaScript UI 对话框中打开/关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有各种简单的 ASP.NET MVC 视图用于 CRUD 操作,它们作为一个简单的网页可以正常工作.我现在将它们集成到网站本身(到内容中),并有例如创建新帖子"之类的链接,它会在选定的 Lightbox 克隆中启动视图(还不知道是哪个,可能是 Colorbox 或 Thickbox,但是没关系).

我想要实现的是,视图本身以某种方式检测到它是在 JavaScript UI 对话框中打开的,因此表单操作(最常见的是使用简单的提交按钮进行 POST)将使用关闭 UI 的逻辑呈现操作执行后的对话框.

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

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

解决方案

你很幸运,我已经做到了!

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

使用这种技术,我还具有非常优雅地降级的优势.我的网站在没有 javascript 的情况下运行得非常完美.链接很好,表单有效,零代码更改从模态感知站点"到普通的旧 html 表单提交.

我所做的只是对默认引擎进行子类化并添加一些 MasterPage 选择位:

视图引擎:

 公共类 ModalViewEngine : VirtualPathProviderViewEngine{公共 ModalViewEngine(){/* {0} = 视图名称或母版页名称* {1} = 控制器名称 */MasterLocationFormats = new[] {~/Views/Shared/{0}.master"};ViewLocationFormats = new[] {"~/Views/{1}/{0}.aspx",~/Views/Shared/{0}.aspx"};PartialViewLocationFormats = new[] {"~/Views/{1}/{0}.ascx",};}受保护的覆盖 IView CreatePartialView(ControllerContext controllerContext, string partialPath){抛出新的 NotImplementedException();}受保护的覆盖 IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath){返回新的 WebFormView(viewPath, masterPath);}公共覆盖 ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache){//你可能需要自定义这个位如果 (controllerContext.HttpContext.Request.IsAjaxRequest())返回 base.FindView(controllerContext, viewName, "Modal", useCache);返回 base.FindView(controllerContext, viewName, "Site", useCache);}protected override bool FileExists(ControllerContext controllerContext, string virtualPath){返回 base.FileExists(controllerContext, virtualPath);}}

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

Modal.Master

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %><div id="modalcontent"><asp:ContentPlaceHolder ID="MainContent" runat="server"/></div>

下一步是创建表单.我使用默认属性名称 = 输入名称,因此我可以轻松地进行模型绑定并保持简单.表格没什么特别的.我看起来就像你通常会这样做.(注意我在我的代码中使用 MVC 2 和 EditorFor() 但这应该无关紧要)这是我的最终 HTML:

HTML 输出

<h2>EditFood</h2><div id="表单"><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="编辑食物"/></表单>

除了非常好的模型绑定之外,您还可以使用 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() });});

在这里,我告诉 ColorBox 为我的编辑链接( Edit Food )打开一个模式窗口.然后绑定到 colorbox 的 complete 事件,将您的 ajaxform 内容与成功回调连接起来,以告诉 ColorBox 关闭模式窗口.就是这样.

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

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

 [UrlRoute(Path="edit/food")]公共 ActionResult EditFood(){返回视图(新食品());}[HttpPost][UrlRoute(Path = "edit/food")]公共 ActionResult EditFood(Food food){返回视图(食物);}

I have various simple ASP.NET MVC views for CRUD operations which work fine on their own as a simple webpage. I will now integrate them into the website itself (into the content) and have for instance links like "Create new post" which would fire up the view in a chosen Lightbox clone (don't know yet which one, maybe Colorbox or Thickbox but that doesn't matter).

What I want to achieve is that the view itself somehow detects that it was opened in a JavaScript UI dialog so that the Form action (most commonly POST using a simple Submit button) will be rendered with a logic that would close the UI dialog after the action has performed.

The way views work now is POST/Redirect/GET. The view should still support this simple pattern when opened directly thru URL in a web browser but should render some additional logic when opened through JavaScript dialog.

Hopefully you understand my question. Any help appreciated

解决方案

Your in luck, I've done this!

So the first thing you need is a new ViewEngine to handle rendering a page without all the normal header/footer stuff that will get in the way of your modal windows. The simpliest way to do that is to use a mostly empty master page for your modal windows. You want the master page switching logic out of the way and in a custom ViewEngine because otherwise each controller method is going to have to have if() else() all over the place detecting IsAjaxRequest(). I like dry, sahara dry.

With this technique I also have the advantage of degrading very gracefully. My site functions without javascript just perfectly. Links are fine, forms work, zero code changes to go from "modal aware site" to plain old html form submits.

All I did was subclass the default engine and add some MasterPage selection bits:

The View Engine:

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);
    }        
}

So my Modal.Master page is very simple. All I have is a div wrapper so I know when something is rendered inside the modal window. This will be helpful when you need to select certain elements with jquery only when the elements are in "modal mode".

Modal.Master

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<div id="modalcontent"><asp:ContentPlaceHolder ID="MainContent" runat="server" /></div>

The next step is to create your form. I use the default property name = input name so I can model bind easily and keep things simple. Nothing special about the form. I looks just like you'd do it normally. ( Note I'm using MVC 2 and EditorFor() in my code but that shouldn't matter ) Here is my final HTML:

HTML Output

<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>

Besides model binding really nicely you can also use the Jquery.Form plugin to have seemless and easy ajax capabilities layered into your application with minimal code. Now I've chosen ColorBox as my modal window script purely because I wanted Facebookesque transparent corners and I like the extensibility points the author added.

Now with these scripts combined you get a really nice combination that makes this technique really stupid easy to do in javascript. The only javascript I had to add was ( inside 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() });
    });

Here I'm telling ColorBox to open a modal window for my edit links ( Edit Food ). Then binding go the colorbox's complete event to wire up your ajaxform stuff with a success callback to tell ColorBox to close the modal window. Thats it.

This code was all done as a proof of concept and thats why the view engine is really lite and there is no validation or other standard form bling. ColorBox and JQuery.Form have tons of extensibility support so customizing this should be easy.

Note this was all done in MVC 2 but here is my controller code anyway just to show how easy this is to do. Remember my proof of concept goal was to get modal windows working in such a way that I didn't have to make any code changes other than set up some basic infrastructure.

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

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

这篇关于简单的 ASP.NET MVC CRUD 视图在 JavaScript UI 对话框中打开/关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆