局部更新時如何更新放置在UpdatePanel之外的控制項

局部更新時如何更新放置在UpdatePanel之外的控制項,本文將提供可能的作法。

UpdatePanel 提供網頁局部更新的功能,讓開發人員可以降低整個網頁回傳到 Server 端所需耗費的等待時間,並避免更新網頁時螢幕閃爍的狀況。由於局部更新的特定,預設只會更新 UpdatePanel 中的控制項內容,在 UpdatePanel 以外的控制項必須在 Server 端使用 ScriptManager.RegisterDataItem 方法,搭配 Client 端 Sys.WebForms.PageRequestManager pageLoading 事件來回應由 Server 端所回傳的資料,才可以在 UpdatePanel 局部更新網頁時也一併更新在 UpdatePanel 外的控制項內容。

假設頁面設計如下,橘色的部分為 UpatePanel ,藍色部分為一般的Div。

 

image

 

程式碼如下:

 

   1:  <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="RegisterDataItemDemo.aspx.cs" Inherits="WebApplication5.RegisterDataItemDemo" %>
   2:   
   3:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   4:   
   5:  <html xmlns="http://www.w3.org/1999/xhtml">
   6:  <head runat="server">
   7:      <title></title>
   8:  </head>
   9:  <body>
  10:      <form id="form1" runat="server">
  11:      <asp:ScriptManager ID="ScriptManager1" runat="server">
  12:      </asp:ScriptManager>
  13:      
  14:      <asp:UpdatePanel ID="UpdatePanel1" runat="server">
  15:          <ContentTemplate>
  16:              <div style="background-color:Orange">
  17:                  <asp:Label ID="Label1" runat="server" Text="我在UpatePanel裡面"></asp:Label>
  18:                  <br />
  19:                  <asp:Label ID="Label2" runat="server" Text="我在UpatePanel裡面"></asp:Label>
  20:                  <br />
  21:                  <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
  22:              </div>
  23:          </ContentTemplate>
  24:      </asp:UpdatePanel>
  25:      <div style="background-color:Aqua">
  26:          <asp:Label ID="Label3" runat="server" Text="我在UpatePanel外面"></asp:Label>
  27:          <br />
  28:          <asp:Label ID="Label4" runat="server" Text="我在UpatePanel外面"></asp:Label>
  29:      </div>
  30:      </form>
  31:  </body>
  32:  </html>

 

筆者在 Button1 的 Click 事件中撰寫下列的程式碼:

 

   1:  protected void Button1_Click(object sender, EventArgs e)
   2:  {
   3:      Label1.Text = "Label 1:" + DateTime.Now.ToString();
   4:      Label2.Text = "Label 2:" + DateTime.Now.ToString();           
   5:  }

 

當使用者按下 Button1 時,不意外地只會更新 Label1和 Label2 (如下圖)。

 

image

 

若要更新位於 UpdatePanel 外面的 Label3 和 Label 4 必須在 Server 端使用 ScriptManager.RegisterDataItem 方法,在局部更新網頁時將資料傳送給控制項。

 

   1:  protected void Button1_Click(object sender, EventArgs e)
   2:  {
   3:      Label1.Text = "Label 1:" + DateTime.Now.ToString();
   4:      Label2.Text = "Label 2:" + DateTime.Now.ToString();
   5:      if (ScriptManager1.IsInAsyncPostBack)
   6:      {
   7:          ScriptManager1.RegisterDataItem(Label3, "Label 3:" + DateTime.Now.ToString(), false);
   8:          JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
   9:          ScriptManager1.RegisterDataItem(Label4, jsSerializer.Serialize("Label 4:" + DateTime.Now.ToString()), true);
  10:      }
  11:  }

 

上述程式碼第8列宣告一個 System.Web.Script.Serialization 命名空間中的 JavaScriptSerializer 類別 來將要回傳給前端的資料序列化為 JSON 格式,預設為非JSON格式回傳資料。

接著在 aspx 中利用 Sys.WebForms.PageRequestManager pageLoading 事件來回應由 Server 端所回傳的資料,並將結果呈現於 Label3 和 Label4。

 

   1:  <script type="text/javascript">
   2:       Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(PageLoadingHandler);
   3:       function PageLoadingHandler(sender, args) {
   4:           var dataItems = args.get_dataItems();
   5:           if ($get('Label3') !== null)
   6:               $get('Label3').innerHTML = dataItems['Label3'];
   7:           if ($get('Label4') !== null)
   8:               $get('Label4').innerHTML = dataItems['Label4'];
   9:       }
  10:  </script>

 

執行結果如下:

 

image

 

完整程式碼如下:

 

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Linq;
   4:  using System.Web;
   5:  using System.Web.UI;
   6:  using System.Web.UI.WebControls;
   7:  using System.Web.Script.Serialization;
   8:   
   9:  namespace WebApplication5
  10:  {
  11:      public partial class RegisterDataItemDemo : System.Web.UI.Page
  12:      {
  13:          protected void Page_Load(object sender, EventArgs e)
  14:          {
  15:              
  16:          }
  17:   
  18:          protected void Button1_Click(object sender, EventArgs e)
  19:          {
  20:              Label1.Text = "Label 1:" + DateTime.Now.ToString();
  21:              Label2.Text = "Label 2:" + DateTime.Now.ToString();
  22:              
  23:              if (ScriptManager1.IsInAsyncPostBack)
  24:              {
  25:                  ScriptManager1.RegisterDataItem(Label3, "Label 3:" + DateTime.Now.ToString(), false);
  26:                  JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
  27:                  ScriptManager1.RegisterDataItem(Label4, jsSerializer.Serialize("Label 4:" + DateTime.Now.ToString()), true);
  28:              }
  29:          }
  30:      }
  31:  }

 

【參考資料】