Tu suerte, he hecho esto!
Así que lo primero que necesita es un nuevo ViewEngine para manejar la representación de una página sin todas las cosas normales de encabezado/pie de página que se interpondrán en el camino de sus ventanas modales. La forma más sencilla de hacerlo es utilizar una página maestra en su mayoría vacía para sus ventanas modales. Desea que la página maestra cambie la lógica fuera del camino y en un ViewEngine personalizado porque, de lo contrario, cada método del controlador tendrá que tener if() else() en todo el lugar detectando IsAjaxRequest(). Me gusta seco, sáhara seco.
Con esta técnica también tengo la ventaja de degradar con mucha gracia. Mi sitio funciona sin javascript perfectamente. Los enlaces están bien, el trabajo de formularios, cambios en el código cero para pasar de un "sitio sensible a los modos" a un simple formulario html antiguo.
único que hice fue subclase el motor por defecto y añadir algunos bits de selección MasterPage:
The View Motor:
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);
}
}
Así que mi página Modal.Master es muy simple. Todo lo que tengo es un envoltorio div, así que sé cuándo algo se procesa dentro de la ventana modal. Esto será útil cuando necesite seleccionar ciertos elementos con jquery solo cuando los elementos estén en "modo modal".
Modal.Master
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<div id="modalcontent"><asp:ContentPlaceHolder ID="MainContent" runat="server" /></div>
El siguiente paso es crear el formulario. Utilizo el nombre de propiedad predeterminado = nombre de entrada para poder modelar el enlace fácilmente y mantener las cosas simples. Nada especial sobre la forma. Me parece que lo harías normalmente.(Tenga en cuenta que estoy usando MVC 2 y EditorFor() en mi código, pero eso no debería importar) Aquí está mi HTML final:
salida 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>
Además de modelo de unión muy bien que pueda utilice también el Jquery.Form plugin para tener capacidades de ajax simples y fáciles de aplicar en capas en su aplicación con un código mínimo. Ahora he elegido ColorBox como script modal de mi ventana simplemente porque quería Facebookesque esquinas transparentes y me gustan los puntos de extensibilidad que el autor ha agregado.
Ahora con estos scripts combinados se obtiene una combinación realmente agradable que hace que esta técnica sea realmente estúpida, fácil de hacer en javascript. La única Javascript he tenido que añadir era (en el interior 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() });
});
Aquí estoy contando ColorBox para abrir una ventana modal para mis enlaces de edición (Edit Alimentos) . A continuación, vincula el evento completo del colorbox para conectar tus elementos ajaxform con una devolución de llamada correcta para indicar a ColorBox que cierre la ventana modal. Eso es.
Este código fue todo hecho como una prueba de concepto y es por eso que el motor de visualización es realmente ligero y no hay validación u otra forma estándar bling. ColorBox y JQuery.Form tienen toneladas de compatibilidad de extensibilidad por lo que personalizar esto debería ser fácil.
Tenga en cuenta que todo esto se hizo en MVC 2, pero aquí está el código de mi controlador para mostrar lo fácil que es esto. Recuerda que mi objetivo de prueba de concepto era lograr que las ventanas modales funcionaran de tal forma que no tuviera que hacer ningún cambio de código más allá de configurar alguna infraestructura básica.
[UrlRoute(Path="edit/food")]
public ActionResult EditFood()
{
return View(new Food());
}
[HttpPost][UrlRoute(Path = "edit/food")]
public ActionResult EditFood(Food food)
{
return View(food);
}
Wow, gracias por esta extensa respuesta. Se ve muy bien. – mare
¿Cómo se conecta este nuevo ViewEngine a una vista existente? Tengo problemas para encontrar esa pieza de código. – mare
No entiendo, el motor de vista hace el cableado, debe hacer cualquier trabajo para conectarlo. – jfar