简单实现AJAX: ASP.NET2.0 中回调的实现及常见问题的解决
本文示例代碼
????接觸asp.net時間并不長,對其中的很多新技術(shù)抱有濃厚的興趣,最近在項目中碰到需要實現(xiàn)無刷新更新數(shù)據(jù)控件的問題,起初考慮使用ajax.pro,atlas實現(xiàn),但感覺這兩種實現(xiàn)對于自己的需求來說都過于重量級了,況且要引用第三方的dll,最終選擇asp.net自帶的回調(diào)接口實現(xiàn)了自己的要求,以下是說明,希望能給剛接觸asp.net回調(diào)的朋友一點幫助。
????要實現(xiàn)無刷新更新數(shù)據(jù)控件需要分三步走:
????????1.?客戶端腳本觸發(fā)回調(diào)方法
????????2. 服務(wù)器端代碼響應(yīng)回調(diào),并更新數(shù)據(jù)控件,將更新后的數(shù)據(jù)控件內(nèi)容(html編碼)發(fā)回客戶端
????????3. 客戶端代碼根據(jù)發(fā)回的內(nèi)容重繪該數(shù)據(jù)控件
????示例代碼中,空白的頁面上有三個DropDownListBox控件DropDownListBox_A,DropDownListBox_B和DropDownListBox_C,最終的目的是實現(xiàn)在頁面不刷新的情況下當(dāng)DropDownListBox_A的選擇更改時動態(tài)的更新DropDownListBox_B和DropDownListBox_C的內(nèi)容,實現(xiàn)聯(lián)動。
??? 在服務(wù)器端,首先要讓自己的頁面實現(xiàn)ICallbackEventHandler接口,如:
????????public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
????然后在頁面上添加如下三個方法及一個公共string,固定套路:
????????private string str_content;
????????//????接收客戶端傳來的參數(shù)
????????public void RaiseCallbackEvent(string the_string)
??????? {
??????????? str_content = the_string;
??????? }
??????? //??? 將結(jié)果發(fā)回客戶端
??????? public string GetCallbackResult()
??????? {
??????????? string[] parts = str_content.Split('|');
??????????? return (string)GetType().GetMethod(parts[0]).Invoke(this, new object[] { parts[1] });
??????? }
????????//? 返回指定控件的Html編碼
??????? private string RenderControl(Control control)
??????? {
??????????? StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
??????????? HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
??????????? control.RenderControl(writer2);
??????????? writer2.Flush();
??????????? writer2.Close();
??????????? return writer1.ToString();
??????? }
????????然后聲明一個更新數(shù)據(jù)控件的方法,比如示例中的
????????public string BindDropDownList_B(string str_index)
??????? {
??????????? //? 簡單綁定
??????????? DropDownList_B.Items.Clear();
??????????? for (int i = 0; i < 20; i++)
??????????? {
??????????????? ListItem newItem = new ListItem();
??????????????? newItem.Text = string.Format("{0} - B{1}", str_index, i.ToString());
??????????????? DropDownList_B.Items.Add(newItem);
??????????? }
??????????? return RenderControl(DropDownList_B);
??????? }
????????public string BindDropDownList_C(string str_index)
??????? {
??????????? DropDownList_C.Items.Clear();
??????????? for (int i = 0; i < 30; i++)
??????????? {
??????????????? ListItem newItem = new ListItem();
??????????????? newItem.Text = string.Format("{0} - C{1}", str_index, i.ToString());
??????????????? DropDownList_C.Items.Add(newItem);
??????????? }
??????????? return RenderControl(DropDownList_C);
??????? }
??????? 在客戶端,你需要將兩個數(shù)據(jù)控件的Html編碼用<span></span>包起來,id分別為span_a和span_b,并在header中聲明如下腳本:
??????? <script language="javascript" type="text/javascript">
??????? //? DropDownList_A的change
??????? function OnChanged()
??????? {
??????????? var context = span_b;
??????????? var theControl = document.getElementById("DropDownList_A");
??????????? //? 調(diào)用服務(wù)器方法BindDropDownList_B,并將A當(dāng)前選擇的index傳過去
??????????? var arg = "BindDropDownList_B|" + theControl.selectedIndex;
????????
??????????? <%= ClientScript.GetCallbackEventReference(this, "arg", "UpdataDropDownList_B", "context")%>;
??????? }
????
??????? function UpdataDropDownList_B(result, context)
??????? {
??????????? //? 重畫控件
??????????? context.innerHTML = result;
??????????? //? 避免同時更新失敗
??????????? setTimeout("elsefunction()", 1);
??????? }
????
??????? function elsefunction()
??????? {
??????????? var context = span_c;
??????????? var theControl = document.getElementById("DropDownList_A");????????
??????????? var arg = "BindDropDownList_C|" + theControl.selectedIndex;
????????
??????????? <%= ClientScript.GetCallbackEventReference(this, "arg", "UpdateDropDownList_C", "context")%>;
??????? }
????
??????? function UpdateDropDownList_C(result, context)
??????? {
??????????? context.innerHTML = result;????
??????? }
??????? </script>
??? 最后在Page_Load中為DropDownList_A添加onchange屬性
??????????? DropDownList_A.Attributes.Add("onchange", "OnChanged()");?
????直接點運行吧,注意看IE的進(jìn)度條。是不是無刷新實現(xiàn)了下拉列表的聯(lián)動:)
????需要說明的是,如果在Javascript腳本的OnChanged中接連兩次回調(diào)服務(wù)器方法的話只有最后一次奏效,并且會有JavaScript報錯,原因是微軟的客戶端回調(diào)實現(xiàn)代碼中有一個缺陷:無論客戶端回調(diào)了多少次,只要有一次回調(diào)完成,則視所有回調(diào)均完成,不是線程安全的!所以上述代碼中使用了setTimeout做了中轉(zhuǎn),具體原因詳見http://developers.de/files/279/download.aspx.
????
??? 以上代碼雖很好的完成了無刷新前提下的數(shù)據(jù)控件更新,但仍有一個問題至今沒有解決,就是雖然控件的數(shù)據(jù)重新更新了,但是狀態(tài)卻還是最后一次PostBack時的狀態(tài)(本例中為初始狀態(tài)),如果你去取某個下拉框的值,仍就是初始值,不知道哪位朋友有這方面的解決辦法,萬分感謝!
轉(zhuǎn)載于:https://www.cnblogs.com/BoKeRen/archive/2006/07/03/441385.html
總結(jié)
以上是生活随笔為你收集整理的简单实现AJAX: ASP.NET2.0 中回调的实现及常见问题的解决的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于VS2005中的Code Snipp
- 下一篇: 讨厌SVN