簡單實現AJAX: ASP.NET2.0 中回調的實現及常見問題的解決

來源:互聯網
上載者:User

本文範例程式碼
    接觸asp.net時間並不長,對其中的很多新技術抱有濃厚的興趣,最近在項目中碰到需要實現無重新整理更新資料控制項的問題,起初考慮使用ajax.pro,atlas實現,但感覺這兩種實現對於自己的需求來說都過於重量級了,況且要引用第三方的dll,最終選擇asp.net內建的回調介面實現了自己的要求,以下是說明,希望能給剛接觸asp.net回調的朋友一點協助。

    要實現無重新整理更新資料控制項需要分三步走:
        1. 用戶端指令碼觸發回調方法
        2. 伺服器端代碼響應回調,並更新資料控制項,將更新後的資料控制項內容(html編碼)發回用戶端
        3. 用戶端代碼根據發回的內容重繪該資料控制項

    範例程式碼中,空白的頁面上有三個DropDownListBox控制項DropDownListBox_A,DropDownListBox_B和DropDownListBox_C,最終的目的是實現在頁面不重新整理的情況下當DropDownListBox_A的選擇更改時動態更新DropDownListBox_B和DropDownListBox_C的內容,實現聯動。

    在伺服器端,首先要讓自己的頁面實現ICallbackEventHandler介面,如:
        public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
    然後在頁面上添加如下三個方法及一個公用string,固定套路:
        private string str_content;
        //    接收用戶端傳來的參數
        public void RaiseCallbackEvent(string the_string)
        {
            str_content = the_string;
        }

        //    將結果發回用戶端
        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();
        }

        然後聲明一個更新資料控制項的方法,比如樣本中的
        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);
        }

        在用戶端,你需要將兩個資料控制項的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");
            //  調用伺服器方法BindDropDownList_B,並將A當前選擇的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的進度條。是不是無重新整理實現了下拉式清單的聯動:)

    需要說明的是,如果在Javascript指令碼的OnChanged中接連兩次回調伺服器方法的話只有最後一次奏效,並且會有JavaScript報錯,原因是微軟的用戶端回調實現代碼中有一個缺陷:無論用戶端回調了多少次,只要有一次回調完成,則視所有回調均完成,不是安全執行緒的!所以上述代碼中使用了setTimeout做了中轉,具體原因詳見http://developers.de/files/279/download.aspx.
    
    以上代碼雖很好的完成了無重新整理前提下的資料控制項更新,但仍有一個問題至今沒有解決,就是雖然控制項的資料重新更新了,但是狀態卻還是最後一次PostBack時的狀態(本例中為初始狀態),如果你去取某個下拉框的值,仍就是初始值,不知道哪位朋友有這方面的解決辦法,萬分感謝!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.