Anthem的原理簡單來說是post到當前頁面.獲得需要更新的內容,再更新原來的頁面.只有上傳檔案的fileUpload控制項是通過建立iframe實現.
這篇隨筆簡略的分析了下anthem完成無重新整理的基本原理,anthem的代碼思路清晰 ,值得去研究下源碼.anthem的程式碼數還是有點多.需要慢慢看 我還是暫時記錄下來,以備以後回顧.
拿最簡單的Label和button控制項分析,實現的效果是 單擊button以後,button將disable,顯示"處理中",接著Label顯示"今天星期一".
代碼:
aspx 代碼
<anthem:button id="btnClick" runat="server" enabledduringcallback="False" onclick="btnClick_Click" text="按鈕" textduringcallback="處理中"></anthem:button>
<anthem:label id="lblResult" runat="server"></anthem:label>
cs 代碼
protected void btnClick_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(5000);
this.lblResult.Text = "今天星期一";
this.lblResult.UpdateAfterCallBack = true;
}
效果如下
圖一 圖二 圖三
處理流程大概:
1.在頁面放入Anthem Label,button控制項
2.頁面第一次載入時 會在頁面上加入Anthem.js的函數 在button的onclick事件中加入
javascript:Anthem_FireCallBackEvent(this,event,'btnClick','',true,'','','處理中',false,null,null,null,true,true);
return false;
這個函數的原型是
function Anthem_FireCallBackEvent(
control,
e,
eventTarget,
eventArgument,
causesValidation,//是否觸發頁面驗證
validationGroup,
imageUrlDuringCallBack,//回調時的圖片顯示
textDuringCallBack,//回調時的文本
enabledDuringCallBack,//是否在回調時禁用控制項
preCallBackFunction,//執行回調前調用的函數
postCallBackFunction,//回調完成後調用的函數
callBackCancelledFunction,//取消時調用的函數
includeControlValuesWithCallBack,
updatePageAfterCallBack//回調後是否更新
)
這個函數是在控制項Render時通過GetCallbackEventReference方法添加上去的.
public static string GetCallbackEventReference(ICallBackControl control, string argument,
bool causesValidation, string validationGroup, string imageDuringCallback)
{
return string.Format(
"javascript:Anthem_FireCallBackEvent(this,event,'{0}','{1}',{2},'{3}','{4}',
'{5}',{6},{7},{8},{9},true,true);",
((Control)control).UniqueID,//控制項ID
argument,//控制項參數
causesValidation ? "true" : "false",
validationGroup,
imageDuringCallback,//
control.TextDuringCallBack,
control.EnabledDuringCallBack ? "true" : "false",
(control.PreCallBackFunction == null || control.PreCallBackFunction.Length == 0) ?
"null" : control.PreCallBackFunction,
(control.PostCallBackFunction == null || control.PostCallBackFunction.Length == 0) ?
"null" : control.PostCallBackFunction,
(control.CallBackCancelledFunction == null || control.CallBackCancelledFunction.Length == 0) ?
"null" : control.CallBackCancelledFunction
);
}
Anthem還會將每個Anthem的控制項儲存下來,從而知道要更新的控制項.
3.載入完成後 顯示按鈕一
4.單擊按鈕後 顯示按鈕二
觸發onclick事件 該事件調用Anthem_FireCallBackEvent函數 這個函數進行了一系列的函數調用
首先調用function Anthem_PreProcessCallBack(
control,
e,
eventTarget,
causesValidation,
validationGroup,
imageUrlDuringCallBack,
textDuringCallBack,
enabledDuringCallBack,
preCallBackFunction,
callBackCancelledFunction,
preProcessOut
)
這個函數做了以下事情
若causesValidation為true 先判斷整個頁面是否通過驗證
若定義了preCallBackFunction 函數就執行該函數
當都通過再往下執行,否則就取消以後的流程
然後用preProcessOut儲存觸發事件的控制項中的初始資訊 等待回調完成後 重新賦值給控制項將控制項中的狀態設定成預定樣式 如button上顯示的文字 設定成textDuringCallBack的文字
接著執行Anthem_FireEvent(eventTarget,eventArgument,
function(result) { //回呼函數
Anthem_PostProcessCallBack(
result,
control,
eventType,
eventTarget,
null,
null,
imageUrlDuringCallBack,
textDuringCallBack,
postCallBackFunction,
preProcessOut
);
},
null,
includeControlValuesWithCallBack,
updatePageAfterCallBack
);
執行函數function Anthem_FireEvent(eventTarget, eventArgument, clientCallBack, clientCallBackArg,
includeControlValuesWithCallBack, updatePageAfterCallBack)
{
var form = Anthem_GetForm();
Anthem_SetHiddenInputValue(form, "__EVENTTARGET", eventTarget);//設定觸發事件的控制項
Anthem_SetHiddenInputValue(form, "__EVENTARGUMENT", eventArgument);//設定事件的參數
Anthem_CallBack(null, null, null, null, null, clientCallBack, clientCallBackArg,
includeControlValuesWithCallBack, updatePageAfterCallBack);
form.__EVENTTARGET.value = "";
form.__EVENTARGUMENT.value = "";
}
執行
Anthem_CallBack(null, null, null, null, null, clientCallBack,
clientCallBackArg, includeControlValuesWithCallBack, updatePageAfterCallBack);
先執行Anthem_PreCallBack函數,若未定義或執行不通過則返回.
然後儲存頁面元素的name和value 作為參數
若頁面沒包含檔案上傳控制項 則利用參數對當前頁面的進行post
若建立XMLHttpRequest錯誤
就執行Anthem_Error(result); 並執行函數Anthem_PostProcessCallBack處理錯誤
若post返回結果錯誤 則執行Anthem_Error
等待Post結果的過程中 發生了...
post到自身頁面時 ,我們可以想象重新開啟了一個相同的頁面,把參數傳遞過去.
pagehandler根據傳遞過來的__EVENTTARGET和__EVENTARGUMENT參數 執行btnClick_Click函數
this.lblResult.Text = "今天星期一";
this.lblResult.UpdateAfterCallBack = true;
render 控制項的時候根據lblResult的UpdateAfterCallBack屬性為true 在label控制項的外圍加上標記
效果如下:
<!--START:lblResult--><span id="lblResult">今天星期一</span><!--END:lblResult-->
接著執行Anthem_UpdatePage 更新頁面
這個函數將遞迴的為原來頁面需要更新的控制項賦予httpRequest得到的新值.如將label中的innerHtml賦值成
<!--START:lblResult--><!--END:lblResult-->
中的值.這樣就完成了當前頁面控制項的無重新整理更新.其他複雜的控制項也是
通過這個原理進行更新的.
執行EvalClientSideScript註冊的指令碼
執行回呼函數Anthem_PostProcessCallBack
回呼函數Anthem_PostProcessCallBack主要把頁面button控制項的狀態還原回去.將button的文字由
"更新中..."還原成"確定" disable還原成"enable".
並執行使用者自訂的postCallBackFunction
執行Anthem_PostCallBack
整個流程就完成了 anthem還做了很多其他工作
這隻是簡略的分析了下anthem完成無重新整理的基本原理,anthem的代碼思路簡單,值得去研究下源碼.
anthem的程式碼數還是有點多.需要慢慢看 我還是暫時記錄下來,以備以後忘記後回顧.