[ASP.NET] 解決 jQuery 配 UpdatePanel 後第二次執行失效問題

摘要:[ASP.NET] 解決 jQuery 配 UpdatePanel 後第二次執行失效問題

前言


  ASP.NET 本身提供的 Ajax 控制項很好用,尤其是 UpdatePanel 控制項應該是很常被使用到的控制項之一,先不考慮 UpdatePanel 會使網頁肥大的問題,UpdatePanel 的確是可以讓開發者很簡單的做到非同步效果。

 

  但是當在使用 jQuery 在 UpdatePanel 上的時後可能會發生以下情形...

  我已經綁定 UpdatePanel 內的 Button 做觸發了,第一次執行是可以跑的,為什麼第二次執行卻沒有反應了呢?

 

  為什麼呢? 原因就是因為放置於 UpdatePanel 內的 Button 控制項當 UpdatePanel 控制項內容進行PostBack 的時後,再回來的 UpdatePanel 內的 Button 控制項已經不是當初所綁定的那個 Button,所以第一次載入時綁定於 UpdatePanel 內Button 控制項的 Script 其實在 UpdatePanel 更新後就已經失效了,如下:

  1. Page Ready > 綁定Script
  2. UpdatePanel: Script Button.Click > 點擊觸發Script的Button (此時有反應)
  3. UpdatePanel: Other Button.Click > 點擊觸發會PostBack的Button
  4. UpdatePanel Ready > UpdatePanel 顯示更新過後的畫面
  5. UpdatePanel: Script Button.Click > 點擊觸發Script的Button (此時已無反應)

 

那要如何解決這個問題呢?  其實只要重新綁定Script就可以了。

以下提供兩種方法:

  1. 在Server端程式執行完成後呼叫 ScriptManager.RegisterStartupScript(Control, Type, String, String, Boolean) 方法重新綁定。
  2. 在Client端取得 Sys.WebForms.PageRequestManager.getInstance() 後呼叫 add_endRequest 方法重新綁定。

 

範例


怎麼做? 實際方法如下:

HTML


        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Path="~/Script/jquery-1.8.2.min.js" />
            </Scripts>
        </asp:ScriptManager>
        無包UpdatePanel<br />
        <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
        <br />
        <asp:Button ID="Button1" runat="server" Text="GetTime" />
        <br />
        <br />
        有包UpdatePanel<asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
                <br />
                <asp:Button ID="Button2" runat="server" Text="GetTime"  />
                 <asp:Button ID="Button3" runat="server" onclick="Button3_Click" 
                    Text="Other PostBack" />
                 <asp:Button ID="Button4" runat="server" onclick="Button4_Click" 
                    Text="Other PostBack + RegisterScript" />
            </ContentTemplate>
        </asp:UpdatePanel>

  可以看到上面的HTML碼中有放了一個正常的 Button,並在 UpdatePanel 中放了另三個 Button,UpdatePanel 中三個 Button 分別是:

  • GetTime: 呼叫 Script 的按鈕
  • Other PostBack: 正常 PostBack 按鈕
  • Other PostBack + RegisterScript: 正常 PostBack + 重新註冊 Script 按鈕

 

Script


            $(function () {
                init();
            });

            function init() {
                $("#<%= button1.clientid="">").click(function () {
                    $("#<%= label1.clientid="">").text(Date());
                    return false;
                });
                $("#<%= button2.clientid="">").click(function () {
                    $("#<%= label2.clientid="">").text(Date());
                    return false;
                });
            }

            var prm = Sys.WebForms.PageRequestManager.getInstance();
            prm.add_endRequest(function () {
                init();
            })

Script 中 init() 是用來綁定按鈕 Click 事件,而最後面一段就是使用前面所提到的第二種方法。

 

Code Behind


    protected void Button4_Click(object sender, EventArgs e)
    {
        ScriptManager.RegisterStartupScript(UpdatePanel1, this.GetType(), "bind", "init();", true);
    }

  在後置程式碼中,於 Button4 Click 事件中使用了 RegisterStartupScript 方法,也就是前面所提到的第一種方法。

 

實際測試

未重新綁定

重新綁定後

 

範例程式碼


TjQueryUpdatePanel.rar

 

補充


另外提供另一個配合 UpdatePanel 的 Plug-in,使用上也很簡單方便: UpdatePanel plug-in

 

參考資料


ScriptManager.RegisterStartupScript 方法

Sys.WebForms.PageRequestManager 類別

 

 


以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)