我想要实现的是,视图本身以某种方式检测到它是在JavaScript UI对话框中打开的,所以Form操作(最常使用简单的Submit按钮的POST)将被渲染为一个逻辑,可以在UI对话框之后关闭UI对话框行动已经执行.
现在工作方式是POST / Redirect / GET.视图应该仍然支持这种简单的模式,直接通过Web浏览器中的URL打开,但是当通过JavaScript对话框打开时应该提供一些额外的逻辑.
希望你明白我的问题.任何帮助赞赏
解决方法
所以你需要的第一件事是一个新的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,"Site",useCache); } protected override bool FileExists(ControllerContext controllerContext,string virtualPath) { return 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输出
<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>
除了模型绑定真的很好,您还可以使用Jquery.Form plugin,以最小的代码将您看似简单的ajax功能分层到您的应用程序中.现在我选择了ColorBox作为我的模态窗口脚本,纯粹是因为我想要脸书的透明角,我喜欢作者添加的可扩展点.
现在,这些脚本结合起来,你会得到一个非常好的组合,这使得这种技术在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为我的编辑链接(编辑食物)打开一个模态窗口.然后绑定到颜色框的完整事件,以连接您的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); }