Friday, April 27, 2012

AJAX UpdatePanel Control

เบื้องต้นเกี่ยวกับ UpdatePanel Control


เป็น ASP.NET Control ที่ทำให้กลุ่ม ASP.NET Control อื่นๆ ที่อยู่ภายใน ContentTemplate ถูกทำงานในรูปแบบ AJAX (Asynchronous JavaScript and XML) และแยกส่วนในการ Update ข้อมูลลงใน Page ออกเป็นแต่ละ UpdatePanel (Partial-Rendering) ในการใช้งาน UpdatePanel จะต้องมีการวาง Control ScriptManager ลงใน Page นั้นๆ เสมอ ซึ่งตัว ScriptManager เพียงตัวเดียวจะทำงานกับหลายๆ UpdatePanel ได้ในแต่ละ Page

ประโยชน์ที่เราจะได้จากการใช้งาน UpdatePanel Control คือ ทำให้ User ไม่เห็นการ Postback เมื่อUser กระทำสิ่งใดๆ บน Page เช่นการกด Sorting บน GridView

การทำงานของ UpdatePanel Control
UpdatePanel และ ScriptManager เป็นการทำงานในระดับ Server Side ในระดับ Client จะมีPageRequestManager ทำหน้าที่ในการจัดการกับ DOM (Document Object Model) เพื่อให้ทำAsynchronous Postback กลับมาที่ Server Side นั้นเกิดขึ้น จริงๆ แล้ว UpdatePanel จะถูกRender ลงใน IE เป็น tag <DIV> และ ScriptMananger จะทำการ Register javascript เพื่อไปเรียกใช้งาน PageRequestManager ตามภาพด้านล่างนี้


เพื่อให้เห็นภาพรวมของการทำงาน UpdatePanel ให้ดู Step และ Diagram ด้านล่างนี้
  1. Request Initial GET ก็เหมือนกับการทำงานที่เป็น Not IsPostback คือการ Load Page นั้นครั้งแรก
  2. Server Side จะทำการ Render ทุกๆ Control ลงไปให้ Client และในจังหวะนี้เองที่ScriptManager จะทำการ Register javascript เพื่อเรียกใช้ PageRequestManager
  3. เมื่อมีการทำ Action ใดๆ ในฝั่ง Client ก็จะเกิดการทำ Asynchronous Postback โดยใช้Event หรือ Method ต่างๆ ของ PageRequestManager เป็นตัวจัดการ
  4. Server ก็จะส่งข้อมูลเป็น JSON หรือ String ธรรมดากลับมาให้กับ UpdatePanel เฉพาะส่วนที่มีการทำ Asynchronous Postback ขึ้นมา (Partial Page Update) 



ตัวอย่างการใช้งาน UpdatePanel Control

เป็น WebApp ที่จะใช้ Insert ข้อมูลพนักงานลงใน Gridview

การเก็บข้อมูลจะถูกจัดเก็บลงใน Object ชื่อ Employee แล้วเอา Object Employee บรรจุลงในGeneric List ชื่อ EmployeeList อีกที สุดท้ายจะต้องมีการเก็บ State ของ EmployeeList ไว้ในViewState

ดังนั้นจำเป็นที่จะต้องมีการทำ Serialize Class Employee เพราะมันจะมีการ ส่ง Object Employee ที่อยู่ใน Generic List ลงใน IE กลับไปกลับมา ระหว่าง Client และ Server ซึ่ง Class Employee ก็จะถูกส่งข้ามเครื่องไปมานั้นเอง

ในการ Load Page ครั้งแรกจะมีการสร้าง Init Data ลงใน GridView เพื่อทำการสร้าง Object ลงใน ViewState ไม่ให้เป็น Nothing

เมื่อมีการกดปุ่ม Insert ก็จะนำค่าใน Textbox FirstNameTextBox และ LastNameTextBox
  • ทำการ Encode Html ออกไป
  • แล้วนำไปสร้างเป็น Object Employee
  • จากนั้นก็ Add ลงใน EmployeeList
  • เก็บ EmployeeList ลงใน ViewState
  • และทำการ Bind ข้อมูล

  
 ใน Page ASPX จะแยก UpdatePanel ออกเป็นสองส่วนคือส่วนของการ Insert (InsertEmployeeUpdatePanel) และ การแสดงข้อมูลพนักงาน (EmployeesUpdatePanel)

ในแต่ละ UpdatePanel มีการกำหนดให้ UpdateMode เป็น Conditional ทั้งคู่ หมายความว่า ถ้ามีการกำหนด Triggers ลงไปก็จะทำ AsyncPostBack ตาม Control หรือ ตาม Event ที่กำหนดอย่างเช่นใน EmployeesUpdatePanel กำหนด UpdateMode เป็น Conditional และมีการกำหนด Trigger ให้รับการทำงานเฉพาะที่เกิดจาก Control InsertButton เท่านั้น
<Triggers>
<asp:AsyncPostBackTrigger ControlID="InsertButton" />
</Triggers>

<%--Page5.aspx--%>
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Page5.aspx.vb" Inherits="Page5" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Enter New Employees</title>
</head>
<body>
<form id="frmPage5" runat="server">
<div>
&nbsp;</div>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
<table>
<tr>
<td style="height: 206px" valign="top">
<asp:UpdatePanel ID="InsertEmployeeUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<table cellpadding="2" border="0" style="background-color: #7C6F57">
<tr>
<td>
<asp:Label ID="FirstNameLabel" runat="server" AssociatedControlID="FirstNameTextBox"
Text="First Name" ForeColor="White" /></td>
<td>
<asp:TextBox runat="server" ID="FirstNameTextBox" /></td>
</tr>
<tr>
<td>
<asp:Label ID="LastNameLabel" runat="server" AssociatedControlID="LastNameTextBox"
Text="Last Name" ForeColor="White" /></td>
<td>
<asp:TextBox runat="server" ID="LastNameTextBox" /></td>
</tr>
<tr>
<td>
</td>
<td>
<asp:LinkButton ID="InsertButton" runat="server" Text="Insert" ForeColor="White" />
<asp:LinkButton ID="Cancelbutton" runat="server" Text="Cancel" ForeColor="White" />
</td>
</tr>
</table>
<asp:Label runat="server" ID="InputTimeLabel"><%=DateTime.Now %></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</td>
<td style="height: 206px" valign="top">
<asp:UpdatePanel ID="EmployeesUpdatePanel" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="EmployeesGridView" runat="server" BackColor="LightGoldenrodYellow"
BorderColor="Tan" BorderWidth="1px" CellPadding="2" ForeColor="Black" GridLines="None"
AutoGenerateColumns="False">
<FooterStyle BackColor="Tan" />
<SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
<PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" HorizontalAlign="Center" />
<HeaderStyle BackColor="Tan" Font-Bold="True" />
<AlternatingRowStyle BackColor="PaleGoldenrod" />
<Columns>
<asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
</Columns>
<PagerSettings PageButtonCount="5" />
</asp:GridView>
<asp:Label runat="server" ID="ListTimeLabel"><%=DateTime.Now %></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="InsertButton" />
</Triggers>
</asp:UpdatePanel>
</td>
</tr>
</table>
</form>
</body>
</html>



'/// Page5.aspx.vb
Imports System.Collections.Generic
Partial Class Page5
Inherits System.Web.UI.Page
Private EmployeeList As List(Of Employee)

Protected Sub Page_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load
If Not IsPostBack Then
EmployeeList = New List(Of Employee)
EmployeeList.Add(New Employee(1, "Banpote""B"))
EmployeeList.Add(New Employee(2, "Tanyawat""T"))
ViewState("EmployeeList") = EmployeeList
Else
EmployeeList = CType(ViewState("EmployeeList"), List(Of Employee))
End If
EmployeesGridView.DataSource = EmployeeList
EmployeesGridView.DataBind()
End Sub

Protected Sub InsertButton_Click(ByVal sender As ObjectByVal e As EventArgs) Handles InsertButton.Click
If String.IsNullOrEmpty(FirstNameTextBox.Text) Or _
String.IsNullOrEmpty(LastNameTextBox.Text) Then Return
Dim employeeID As Integer = EmployeeList(EmployeeList.Count - 1).EmployeeID + 1
Dim lastName As String = Server.HtmlEncode(FirstNameTextBox.Text)
Dim firstName As String = Server.HtmlEncode(LastNameTextBox.Text)
FirstNameTextBox.Text = String.Empty
LastNameTextBox.Text = String.Empty
EmployeeList.Add(New Employee(employeeID, lastName, firstName))
ViewState("EmployeeList") = EmployeeList
EmployeesGridView.DataBind()
EmployeesGridView.PageIndex = EmployeesGridView.PageCount
End Sub


Protected Sub CancelButton_Click(ByVal sender As ObjectByVal e As EventArgs) Handles Cancelbutton.Click
FirstNameTextBox.Text = String.Empty
LastNameTextBox.Text = String.Empty
End Sub


<Serializable()> _
Public Class Employee
Private _employeeID As Integer
Private _lastName As String
Private _firstName As String
Public ReadOnly Property EmployeeID() As Integer
Get
Return _employeeID
End Get
End Property
Public ReadOnly Property LastName() As String
Get
Return _lastName
End Get
End Property
Public ReadOnly Property FirstName() As String
Get
Return _firstName
End Get
End Property
Public Sub New(ByVal employeeID As IntegerByVal lastName As StringByVal firstName As String)
_employeeID = employeeID
_lastName = lastName
_firstName = firstName
End Sub
End Class

End Class

No comments:

Post a Comment