Chuyển trang ASP.NET sang Ajax với Magic
Ajax.NET Là một trong những công nghệ nền tảng của Web 2.0, Ajax đã
và đang làm thay đổi cách chúng ta nhìn nhận và sử dụng các ứng dụng
web. Cùng với sự phát triển của các trang web hỗ trợ Ajax, các công cụ
giúp các nhà phát triển nhanh chóng xây dựng các trang web này cũng đã
ra đời và ngày càng phát triển. Một trong số đó là thư viện Ajax.NET
Trong bài viết này, tôi sẽ giới thiệu một công cụ khác hỗ trợ phát triển
Ajax không kém phần hiệu quả, đó là MagicAjax.NET (gọi tắt là
MagicAjax). MagicAjax.NET giúp bạn đưa trang Web ASP.NET hiện có
sang hỗ trợ Ajax một cách trực quan mà không cần phải thay thế các điều khiển ASP.NET đã có
và/hoặc viết thêm mã JavaScript.
MagicAjax.NET là một dự án mã nguồn mở (C#) tuân theo các điều khoản trong giấy phép GNU
Lesser GPL. Hiện phiên bản mới nhất là 0.3.0. Bạn có thể tải về thư viện, mã nguồn, các ví dụ
cũng như tài liệu từ trang web chính thức của dự án .
Các đặc điểm của MagicAjax
• Tích hợp:
- Chỉ cần vài dòng thiết lập cấu hình trong web.config là có thể dùng MagicAjax.
- Chỉ cần thêm vào một điều khiển (AjaxPanel) để trang web của bạn hỗ trợ Ajax.
• Sử dụng:
Đặt phần trang web mà bạn muốn hỗ trợ Ajax vào trong AjaxPanel, công việc còn lại sẽ do
MagicAjax Framework đảm nhiệm.
- Có thể đưa MagicAjax vào Visual Studio để sử dụng một cách trực quan.
- Không cần viết mã JavaScript để xử lí phía trình duyệ
t.
• Lập trình:
- Trong phần lớn trường hợp, để sử dụng MagicAjax, bạn chỉ cần thêm các AjaxPanel mà không
cần thay đổi mã nguồn.
- MagicAjax thay hàm PostBack bằng hàm callback của Ajax (AjaxCall).
- Có thể dùng cả hàm PostBack và chức năng Ajax trong cùng một trang, chỉ những phần nằm
trong AjaxPanel mới gọi AjaxCall thay cho PostBack.
- ViewState của trang web được chia sẻ giữa PostBack và AjaxCall, khi có một thay đổi tạo bởi
AjaxCall, PostBack có thể dùng thay đổi đó và ngược lại.
- Bạn có thể điều khiển AjaxCall tương tự như PostBack, sử dụng lập trình ASP.NET phía
server.
- MagicAjax nhận ra những thay đổi trong khi gọi AjaxCall, và gửi một đoạn mã JavaScript nhỏ
nhất có thể để phản hồi các thay đổi đến trình duyệt.
- Có thể dùng mã để điều khiển.
• Tùy biến:
- Cung cấp nhiều thiết lập cho phép bạn sử dụng linh hoạt.
- Có thể tùy biến các điều khiển ASP.NET khi dùng chúng với MagicAjax.
- Có thể khai báo hàm AjaxCall sẽ gọi đồng bộ hay không đồng bộ đối với tất cả các điều khiển
nằm trong AjaxPanel hay là chỉ với một điều khiển riêng biệt nằm trong đó.
- Bạn có thể khai báo một điều khiển nào đó của AjaxPanel sẽ gọi thuần PostBack.
- Thiết kế hướng đối tượng rõ ràng giúp bạn dễ dàng mở rộng Magic và tạo các điều khiển Ajax
của chính bạn.
• Tương thích:
- MagicAjax hỗ trợ hầu hết các trình duyệt hiện nay như Internet Explorer, Firefox, Opera và
Netscape.
- Nếu trình duyệt không hỗ trợ hoặc người dùng cấm tính năng JavaScript trong trình duyệt,
trang web sẽ tự động chuyển về sử dụng PostBack.
Tích hợp MagicAjax
Mục đích của MagicAjax là hỗ trợ chuyển từ trang web ASP.NET hiện có sang Ajax một cách
d
ễ dàng nhất, do vậy việc tích hợp MagicAjax hạn chế tối đa viết mã. Các bước thực hiện như
sau:
1) Thay đổi web.config:
Bạn nên đăng kí MagicAjax ở section system.web trong file web.config như sau:
<httpModules>
<add name=”MagicAjax” type=”MagicAjax.MagicAjaxModule, MagicAjax” />
</httpModules>
Lúc này, MagicAjax sẽ sử dụng các thiết lập mặc định. Nếu muốn thay đổi các thiết lập, bạn có
thể chỉnh sửa file web.config theo ý mình (một số chỉnh sửa quan trọng sẽ được giới thiệu trong
phần sau của bài viết).
2) Thêm các điều khiển vào trang web:
Dùng một tag để đăng kí sử dụng namespace cho các điều khiển MagicAjax ở đầu trang web:
<%@ Register TagPrefix=”ajax” Namespace=”MagicAjax.UI.Controls”
Assembly=”MagicAjax” %>
Sau đó, bạn có thể khai báo một đ
iều khiển theo cấu trúc:
<ajax:AjaxPanel id=”AjaxPanel1” runat=”server”></ajax:AjaxPanel>
Bạn hãy để ý đến tag <ajax:AjaxPanel> và </ajax:AjaxPanel>, tag này có nhiệm vụ giới hạn
“tầm ảnh hưởng” của Ajax. Chỉ những điều khiển nào được đặt trong tag này mới hỗ trợ Ajax,
còn không thì chúng chỉ là những điều khiển thông thường. Điều này cho phép bạn sử dụng Ajax
một cách linh hoạt.
3) Thêm thư viện MagicAjax:
Bạn tạo một thư mục bin nằ
m trong thư mục chứa trang web của mình. Copy file MagicAjax.dll
vào, thế là xong. Bạn hãy mở trình duyệt và xem sự khác biệt.
4) Tích hợp MagicAjax trong môi trường Visual Studio (từ phiên bản 2003 trở lên):
Từ menu Tools, chọn Add/Remove Toolbox Items (chọn Toolbox Items với VS 2005), nhấn vào
Browse và chỉ đến file MagicAjax.dll. Các điều khiển sẽ được thêm vào trong toolbox như bạn
thấy dưới đây:
Lúc này, bạn có thể tạo một AjaxPanel để kéo-thả các điều khiển vào đó:
Các bước còn lại hoàn toàn như
đã trình bày ở trên, chỉ có điều bạn làm một cách “trực quan”
hơn trong môi trường VS mà thôi (bạn chỉ cần sửa lại web.config, còn các điều khiển nằm trong
AjaxPanel sẽ được khai báo tự động hỗ trợ Ajax).
Sử dụng MagicAjax
AjaxPanel là nhân của MagicAjax, tương tự như panel của ASP.NET, các thành phần bên trong
nó được hiển thị trực quan và bạn có thể thiết lập các thuộc tính của các điều khiển web, thay đổi
thuộc tính Visible của nó... Hàm PostBack của tất cả các điều khiển nằm trong AjaxPanel được
thay thế bằng AjaxCall, trừ khi nó được khai báo khác. Thuộc tính AjaxCallConnection của các
điều khiển trong AjaxPanel có thể thiết lập thành:
Asynchronous (không đồng bộ - mặc định): AjaxCall sẽ được sử dụng dưới dạng nền
(background), mã lệnh sẽ tiếp tục thực hiện mà không cần đợi nó trả về.
Synchronous (đồng bộ): trình duyệt sẽ đợi cho đến khi AjaxCall kết thúc.
None: các điều khiển này sẽ dùng hàm PostBack thông thường.
Thuộc tính ExcludeFlags của AjaxPanel xác định xem thành phần nào trong form sẽ bị loại khi
một hàm AjaxCall gửi đến máy chủ, vì thế giảm số lượng gọi AjaxCall. Nó thiết lập thuộc tính
ExcludeFlags của MagicAjax cho các điều khiển ASP.NET (bạn sẽ thấy ở phần sau). Một
AjaxPanel con sẽ tự động thừa kế thuộc tính này của cha nó. Nó có thể đánh dấu thêm các thành
phần của form để loại bỏ thông qua thuộc tính ExcludeFlags của nó, nhưng nó sẽ không thể gửi
đến máy chủ các thành phần của form đã được đánh dấu để loại bỏ bởi cha của nó.
Để giảm lượng HTML cần gửi đến client, MagicAjax định nghĩa các “chủ thể HTML” riêng biệt.
Một AjaxPanel con nằm trong một AjaxPanel cha, sẽ định nghĩa chủ thể HTML riêng biệt với
cha nó. AjaxPanel cha sẽ bỏ qua mã HTML của AjaxPanel con, chỉ có AjaxPanel con chịu trách
nhiệm phản hồi với chủ thể của nó trên client. Vì vậy, bạn có thể giảm số lượng AjaxCall, bằng
cách thêm nhiều AjaxPanel để khai báo nhiều chủ thể HTML nhỏ hơn. Ví dụ, nếu bạn đặt một
bảng trong một AjaxPanel, và thay đổi một trong số các cell của nó trong một AjaxCall, toàn bộ
mã HTML của bảng đó sẽ được gửi đến client. Nếu bạn thêm một AjaxPanel cho mỗi cell, chỉ có
mã HTML của cell đã thay đổi được gửi đến client.
AjaxPanel có thuộc tính AjaxLocalScope là true được gọi là AjaxZone. Khi một điều khiển nằm
trong AjaxZone gọi một hàm AjaxCall, chỉ các giá trị của các thành phần trong form nằm trong
AjaxZone được gửi đến máy chủ. Máy chủ sẽ kiểm tra các thay đổi và chỉ phản hồi đến các
AjaxPanel nằm trong AjaxZone đó. Điều này sẽ làm giảm lưu chuyển Ajax và tăng khả năng đáp
ứng của máy chủ. Mục đích của nó là tạo các phần riêng rẽ và độc lập với nhau trên cùng một
trang, tương tự như các UserControl. Một AjaxZone có thể chứa các AjaxZone khác. Một điều
khiển thuộc về AjaxZone là cha trực tiếp củ
a nó.
Bạn có thể thiết lập các thuộc tính sau với các điều khiển ASP.NET để quyết định cách chúng
được dùng bởi MagicAjax:
- AjaxCall (“Async”, “Sync” hoặc “None” ): Khi bạn thêm thiết lập AjaxCall với giá trị là
“Async” hoặc “Sync” cho một điều khiển sử dụng chức năng PostBack (như Button, LinkButton,
CheckBox,...), chức năng này sẽ được thay thế bằng chức năng Ajax, ngay cả khi điều khiển đó
không nằm trong một AjaxPanel. Khi bạn thêm thiết lập AjaxCall với giá trị “None” vào một
điều khiển nằm trong AjaxPanel, điều khiển này sẽ dùng PostBack thay cho AjaxCall. Bằng cách
thêm thuộc tính AjaxCall, bạn có thể ghi chồng thuộc tính AjaxCallConnection của AjaxPanel
chứa nó (ví dụ, nếu AjaxPanel được thiết lập để làm việc không đồng bộ, bạn có thể thêm
AjaxCall với giá trị “sync” để nó thực hiện một lời gọi AjaxCall đồng bộ). Thuộc tính AjaxCall
sẽ được áp dụng cho tất cả các con cháu của điều khiển, thế nên nếu bạn thêm nó vào một khung
ASP.NET đơn thuần, tất cả các điều khiển nằm trong đó sẽ chịu ảnh hưởng của thuộc tính
AjaxCall.
- ExcludeFromPost (“true” hoặc “false”): Khi thực hiện một lời gọi AjaxCall, client gửi các giá
trị của các thành phần của form về máy chủ như là dữ liệu POST. Nếu điều khiển chỉ đơn giản
dùng để hiển thị thông tin, và không nhận thông tin người dùng nhập vào, bạn có thể thêm thuộc
tính ExcludeFromPost với giá trị là “true”, thì giá trị của điều khiển đó sẽ không được gửi đến
máy chủ. Bạn có thể giảm lưu lượng thông tin không cần thiết giữa client và máy chủ bằng cách
thêm thuộc tính này cho các điều khiển như readonly Textbox hay Label.
- AjaxLocalScope (“true” hoặc “false”): Thiết lập này điều khiển hoạt động tương tự một
AjaxZone (đã nói ở phần trên).
- ExcludeFlags (biểu thức): Xác định xem thành phần nào của form sẽ bị loại bỏ khi gửi đến
server trong một lời gọi AjaxCall. Thành phần của form sẽ bị loại bỏ khi gọi AjaxCall từ một
điều khiển hay từ các con cháu của nó. Thuộc tính này nên được thiết lập với một biểu thức số
học mà giá trị trả về là một số nguyên. Bạn có thể dùng các hằng số của JavaScript như
excfViewState, excfFingerprints, excfUserHidden, excfAllHidden, excfFormElements,
excfAllElements.
Ví dụ:
<asp:button excludeflags=”excfFormElements | excfViewState” ...>
Chú ý là tất cả các thuộc tính trên đều có thể dùng mã để thiết lập. Các giá trị của chúng có thể
thay đổi trong một AjaxCall:
Ví dụ:
Button1.Attributes[“ajaxcall”] = “async”;
Thiết lập MagicAjax
Thiết lập web.config
Bạn có thể thay đổi các thiết lập mặc định của MagicAjax trong section configuration của
web.config. Các thiết lập này sẽ được áp dụng cho tất cả các trang có trong ứng dụng của bạn.
Nếu bạn bỏ sót một thiết lập nào đó, MagicAjax sẽ sử dụng giá trị mặc định. Dưới đây là một ví
dụ:
<configSections>
<section name=”magicAjax” type=”MagicAjax.Configuration.MagicAjaxSectionHandler,
MagicAjax”/>
</configSections>
<magicAjax outputCompareMode=”HashCode” tracing=”false”>