ASP.NET MVC框架拯救UpdatePanel
什么是“拯救UpdatePanel for ASP.NET MVC框架”呢?ASP.NET AJAX中的UpdatePanel相信大家都有所了解。可惜的是,ASP.NET MVC框架的誕生“毀滅”了大量基于PostBack的控件,首當(dāng)其沖地可能就是UpdatePanel了。如果沒有 PostBack,UpdatePanel就失去了全部作用,甚至不如一些綁定控件,至少它們還能夠用于展示。為UpdatePanel長吁短嘆之后,我們不禁又開始懷念UpdatePanel的優(yōu)勢:“透明”。在UpdatePanel的幫助下,實(shí)現(xiàn)AJAX操作對(duì)于開發(fā)人員幾乎完全透明。我們要做的僅僅是將需要AJAX更新的內(nèi)容用UpdatePanel包裝起來,一切都是那么優(yōu)雅。
我們能否在ASP.NET MVC中拯救UpdatePanel呢?也許是可以的吧,但這更像是一個(gè)“不可能完成的任務(wù)”。我不是傳說中的阿湯哥,因此重新為ASP.NET MVC量身定制一個(gè)AJAX解決方案似乎更為可行。雖然我們不會(huì)苛求一個(gè)新生事物從誕生開始就趨向完美,但即使只是一個(gè)原型,它也必須嚴(yán)格遵守的一些原則:
不得破壞MVC中的協(xié)議(協(xié)作,職責(zé)等等)
對(duì)開發(fā)人員盡可能地透明
Nikhil Kothari曾經(jīng)提出了他在ASP.NET MVC框架下的AJAX解決方案。如果您還不了解他的做法,那么我先在這里進(jìn)行一點(diǎn)概括。Nikhil擴(kuò)展了Controller使之支持一種Ajax操作,于是我們在代碼中就可以寫如下代碼:
- publicclassTaskListController:AjaxController{
- ...
- publicvoidCompleteTask(inttaskID){
- if(String.IsNullOrEmpty(Request.Form["deleteTask"])==false){
- InvokeAction("DeleteTask");
- return;
- }
- Tasktask=_taskDB.GetTask(taskID);
- if(task!=null){
- _taskDB.CompleteTask(task);
- }
- if(IsAjaxRequest){
- if(task!=null){
- RenderPartial("TaskView",task);
- }
- }
- else{
- RedirectToAction("List");
- }
- }
- ...
- }
與AjaxController類似,Nikhil也為ViewPage和ViewControl提供了一些擴(kuò)展方法,因此目前在View(List.aspx)中我們就能看到如下的代碼:
- <divid="taskList">
- <%foreach(TasktaskinTasks){%>
- <div>
- <%this.RenderPartial("TaskView",task);%>
- </div>
- <%}%>
- </div>
在View和Controller中都存在對(duì)于RenderPartiel方法的調(diào)用,它們的作用就是向客戶端輸出一個(gè)“Partial Template”生成的HTML代碼。而在ASP.NET MVC的默認(rèn)配置中,Partial Template即為User Control。而在TaskView這個(gè)Partial Template中可以看到一些輔助方法:
- <divid="taskItem<%=Task.ID%>"class="taskPanel">
- <%Ajax.Initialize();%>
- <%this.RenderBeginAjaxForm(
- Url.Action("CompleteTask"),
- new{
- Update="taskItem"+Task.ID,
- UpdateType="replace",
- Completed="endUpdateTask"});%>
- <inputtype="hidden"name="taskID"value="<%=Task.ID%>"/>
- <inputtype="submit"class="completeButton"name="completeTask"value="Done!"/>
- <inputtype="submit"class="deleteButton"name="deleteTask"value="Delete"/>
- <span><%=Html.Encode(Task.Name)%></span>
- <%this.RenderEndForm();%>
- <%Ajax.RenderScripts();%>
- </div>
這些輔助方法的作用是生成一些觸發(fā)AJAX更新的標(biāo)簽及腳本,當(dāng)用戶點(diǎn)擊RenderBeginAjaxForm與RenderEndForm方法生成的tag之間的提交按鈕時(shí),網(wǎng)頁將會(huì)向服務(wù)器端發(fā)出一個(gè)AJAX請(qǐng)求,而服務(wù)器端的Action并最終會(huì)通過RenderPartial方法輸出一個(gè)Partial Template生成的HTML。服務(wù)器端最終輸出的HTML將會(huì)被替換或添加到頁面的某個(gè)元素內(nèi)。這就形成了一個(gè)AJAX效果。這個(gè)解決方案從某些方面看上去很酷,尤其是生成的代碼可以添加到某個(gè)元素中,而不單單是如同UpdatePanel的替換,例如Nikhil在他的例子中就使用了這個(gè)特性實(shí)現(xiàn)了一個(gè)添加功能。不過如果使用之前提出的原則來衡量的話,似乎這個(gè)解決方案并不十分理想。以上介紹ASP.NET MVC框架拯救UpdatePanel
【編輯推薦】