你好運,我已經做到了!
所以你需要的第一件事就是用一個新的ViewEngine來處理渲染頁面,而不需要所有正常的頁眉/頁腳的東西,這些東西會妨礙你的模態窗口。最簡單的方法是爲模態窗口使用大部分爲空的主頁面。您希望主頁面切換邏輯不會出現在自定義ViewEngine中,否則每個控制器方法都必須在檢測IsAjaxRequest()的地方遍歷if()else()。我喜歡乾燥的撒哈拉沙漠。
有了這種技術,我也有非常優雅地退化的優勢。我的網站功能完全沒有JavaScript。鏈接很好,表單工作,零代碼更改從「模態意識網站」轉到普通的舊HTML表單提交。
我所做的只是子類的默認引擎,並添加一些母版選擇位:
視圖引擎:
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);
}
}
所以我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作爲我的模式窗口腳本,純粹是因爲我想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的完整事件,通過成功回調連接你的ajaxform,告訴ColorBox關閉模式窗口。而已。
這段代碼都是作爲概念驗證完成的,這就是爲什麼視圖引擎非常簡潔並且沒有驗證或其他標準形式的金光閃閃。 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);
}
哇,謝謝你的廣泛答覆。看起來很棒。 – mare 2009-12-05 13:19:26
如何將這個新的ViewEngine連接到現有的View?我無法找到這段代碼。 – mare 2009-12-09 10:29:11
我不明白,視圖引擎是否連線,你應該做任何工作來連接它。 – jfar 2009-12-09 15:51:40