摘要:[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 更新後就已經失效了,如下:
- Page Ready > 綁定Script
- UpdatePanel: Script Button.Click > 點擊觸發Script的Button (此時有反應)
- UpdatePanel: Other Button.Click > 點擊觸發會PostBack的Button
- UpdatePanel Ready > UpdatePanel 顯示更新過後的畫面
- UpdatePanel: Script Button.Click > 點擊觸發Script的Button (此時已無反應)
那要如何解決這個問題呢? 其實只要重新綁定Script就可以了。
以下提供兩種方法:
- 在Server端程式執行完成後呼叫 ScriptManager.RegisterStartupScript(Control, Type, String, String, Boolean) 方法重新綁定。
- 在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 方法,也就是前面所提到的第一種方法。
實際測試
未重新綁定
重新綁定後
範例程式碼
補充
另外提供另一個配合 UpdatePanel 的 Plug-in,使用上也很簡單方便: UpdatePanel plug-in
參考資料
ScriptManager.RegisterStartupScript 方法
Sys.WebForms.PageRequestManager 類別
以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)