Tuesday, June 19, 2007

Client Callbacks without Postbacks in ASP.NET ตอนที่ 2

ในตอนที่แล้ว ผมได้อธิบายถึงหลักการในการเขียนโปรแกรม Callback without Postbacks ไปแล้ว ซึ่งทำให้เบราว์เซอร์ไม่จำเป็นต้อง Postback กลับไปยังเซิร์ฟเวอร์ทั้งเพจ content โดยใช้ Interface ชื่อ ICallbackEventHandler โดย implement เมธอด RaiseCallbackEvent และ GetCallbackResult มาในตอนนี้ ผมจะพูดถึงขึ้นตอนการเขียนโค้ดครับ

การสร้างเพจ Callbacks without Postbacks
ผมแสดงตัวอย่างเป็นขั้นตอน ดังนี้

1. ก่อนอื่นให้สร้างเพจ aspx ตามรูป

  • TextBox1 เป็นตัวรับข้อความ
  • TextBox2 เป็นตัวแสดงข้อความ
  • Button เป็น HTML control (ไม่มี runat="server") เป็นตัวเรียกฟังก์ชัน Callback
2. ทำการ Implement ICallbackEventHandler
  
Partial Class _Default
Inherits System.Web.UI.Page
Implements ICallbackEventHandler
...
End Class

3. เขียนไคลเอ็นต์สริปต์เพื่อเรียกใช้เมธอด callback ในเพจ aspx ระหว่าง head tag
      
<head>
<script type="text/javascript">
01 function ShowText()
02 {
03 nametxt = document.getElementById("TextBox1").value;
04 CallServer(nametxt);
05 }
06 function ReceiveServerData(retVal)
07 {
08 document.getElementById("TextBox2").value = retVal;
09 }
</script>
<head>

และกำหนดอีเว็นต์ OnClick ของ Button เพื่อเรียกฟังก์ชัน ShowText()

<input id="Button1" type="button" value="button"
onclick="return ShowText();" />

อธิบายได้ดังนี้
  • โค้ดบันทัดที่ 03 เป็นการดึง value ของ TextBox1 มา้เก็บไว้ที่ตัวแปร nametxt
  • โค้ดบันทัดที่ 04 เป็นการเรียกฟังก์ชันชื่อ CallServer ซึ่งเป็นสคริปต์ฟังก์ชัน ที่เราจะเขียนขึ้นใน Code-behind อีกที เพื่อเรียกใช้ฟังก์ชันในเซิร์ฟเวอร์ต่อ
  • ฟังก์ชัน ReceiveServerData เป็นฟังก์ชัน CallBack ที่รับผลลัพท์จากเซิร์ฟเวอร์กลับมา โดยฟังก์ชั่นนี้ จะถูกเรียกหลังจากที่การประมวลผลบนเซิร์เวอร์ เสร็จเรียบร้อยแล้ว ส่วนมากใช้เพื่อแสดงผลลัพท์ที่ได้รับกลับมา โดยมีโค้ดบันทัดที่ 08 เป็นการ assign ค่าที่ได้รับกลับมาแสดงใน TextBox2
4. เขียนโค้ดใน page_load อีเว็นต์ เพื่อสร้างสคริปต์ฟังก์ชัน CallServer ที่ถูกเรียกใช้จากข้อ 3 บันทัดที่ 04 โดยฟังก์ชันนี้เป็นฟังก์ชันที่ทำงานเสมือนการ PostBack กลับไปยังเซิร์เวอร์

       Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
01 Dim callbackRef As String
02 callbackRef = ClientScript.GetCallbackEventReference(Me, "arg", "ReceiveServerData", "context")
03 Dim callbackScript As String
04 callbackScript = "function CallServer(arg, context) {" & callbackRef & "; }"
05 ClientScript.RegisterClientScriptBlock(Me.GetType, "CallServerScript", callbackScript, True)
End Sub

อธิบายโค้ด
  • ในอีเว็นต์ page_load นี้จะทำการเพิ่มไคลเอ็นต์สคริปต์โค้ด ที่จะ PostBack กลับไปยังเซิร์เวอร์ ให้สังเกตว่า "ReceiveServerData" นั้นเป็นชื่อฟังก์ชันสคริปต์ ที่เราได้สร้างไว้ตั้งแต่ข้อ 3 ซึ่งได้อธิบายไปแล้วว่าเป็นฟังก์ชันที่ใช้เพื่อแสดงผลลัพท์ที่ได้รับกลับมา
  • ในบันทัด 04 เป็นการสร้างฟังก์ชันชื่อ CallServer ที่จะถูกเรียกใช้จากฟังก์ชัน ShowText ที่เขียนไว้แล้วในข้อที่ 3
  • บันทัดที่ 05 เป็นการบอกให้เพิ่มสคริปต์นี้เข้าไปในเพจ aspx ตอน run-time
5. ทำการ implement เมธอดดังนี้ ใน code-behind
    private retval as String
Public Sub RaiseCallbackEvent(ByVal eventArgument As
String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
retval = "Hello world : " & eventArgument & ", " & Now.Date.ToShortDateString
End Sub

Public Function GetCallbackResult() As String Implements
System.Web.UI.ICallbackEventHandler.GetCallbackResult
Return retval
End Function
  • เมธอด RaiseCallbackEvent เป็นเมธอดที่ทำงานเมื่อมีการเรียกใช้ เมธอด CallServer ที่ได้สร้างไว้ในข้อ 4 โดยทำการ concat ข้อมูลที่ได้ส่งมาใน eventArgument พารามิเตอร์ ซึ่งก็คือข้อมูลใน TextBox1.Text นั่นเอง เพราะถ้าดูจากโค้ดในข้อ 3 แล้ว ในบันทัดที่ 04 มีการเรียกใช้เมธอด CallServer โดยส่งข้อมูล TextBox1.Text เป็นพารามิเตอร์
  • เมธอด GetCallbackResult เป็นเมธอดคืนผลลัพท์ไปยังเมธอด Callback ที่ได้ระบุไว้ขณะสร้างฟังก์ชัน CallServer ในข้อที่ 4 บันทัดที่ 02 ซึ่งเมธอด Callback นั้นก็คือ ReceiveServerData โดยใน ReceiveServerData ก็จะรับข้อมูลที่ได้ส่งมาจาก GetCallbackResult
  • ส่วนตัวแปร retval เป็นตัวแปรแบบโกลบอลเพื่อเก็บค่าของข้อมูลระหว่างเมธอด RaiseCallbackEvent และ GetCallbackResult

ลองทดสอบโดย run โปรแกรมและลองใส่ชื่อใน TextBox1 แล้วกดปุ่ม Button ข้อความและแสดงบน TextBox2 โดยที่เพจไม่มีการ refresh


โค้ดในส่วนของ code-behind ทั้งหมด
Partial Class _Default
Inherits System.Web.UI.Page
Implements ICallbackEventHandler

Private retval As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim sb As New StringBuilder
Dim callbackRef As String
callbackRef = ClientScript.GetCallbackEventReference(Me, "arg", "ReceiveServerData", "context")
Dim callbackScript As String
callbackScript = "function CallServer(arg, context) {" & callbackRef & "; }"
ClientScript.RegisterClientScriptBlock(Me.GetType, "CallServer", callbackScript, True)
End Sub

Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
Return retval
End Function

Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
retval = "Hello world : " & eventArgument & ", " & Now.Date.ToShortDateString
End Sub
End Class

และโค้ดเพจ Default.aspx ทั้งหมด
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<!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 runat="server">
<title>Untitled Page</title>
<script type="text/javascript">
function ShowText()
{
nametxt = document.getElementById("TextBox1").value;
CallServer(nametxt);
}
function ReceiveServerData(retVal)
{
document.getElementById("TextBox2").value = retVal;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Font-Bold="True" Font-Italic="False" Font-Size="Large"
Font-Underline="True" Text="Client Callbacks Without Postbacks in ASP.NET"></asp:Label>
<br />
<br />
<asp:TextBox ID="TextBox1" runat="server">TextBox1</asp:TextBox>
<br />
<input id="Button1" type="button" value="button" onclick="return ShowText();" /><br />
<asp:TextBox ID="TextBox2" runat="server" Width="304px">TextBox2</asp:TextBox> <br />
</div>
</form>
</body>
</html>

ด้วยความสามารถในการ Callback without Postback นี้เอง ทำให้เราสามารถเขียนโปรแกรม ASP.NET ได้โดยปราศจากการ submit ทั้งเพจ เพื่อเพิ่มความรวดเร็วในการทำงานของเว็บเพจ ให้ทำงานได้อย่างรวดเร็วและราบรื่น

No comments: