Dojo đã được tạo ra vào năm 2004 để giúp cho quá trình phát triển các ứng dụng web DHTML và JavaScript dễ dàng hơn, ẩn giấu nhiều mâu thuẫn giữa các trình duyệt thường thấy trong các trình duyệt web hiện đại. Điều này cho phép đặt trọng tâm vào việc thực hiện các hàm chứ không phải tinh chỉnh mã để cho nó làm việc trên mọi trình duyệt. Dojo thuộc sở hữu của quỹ Dojo, được thành lập năm 2005 bởi Alex Russell và Dylan Schiemann. Dojo là phần mềm mã nguồn mở (OSS) và được phát hành theo giấy phép-kép (bạn có thể chọn một giấy phép nào bạn muốn tuân thủ) với cả hai Giấy phép miễn phí có tính học thuật (AFL) và giấy phép BSD có sửa đổi có sẵn.
Các tính năng của Bộ công cụ Dojo được phổ biến theo bốn gói riêng biệt. Sự phân chia này cho phép các nhà phát triển giữ kích thước tệp thư viện ở mức tối thiểu, đảm bảo hiệu năng của ứng dụng của họ không phải chịu gánh nặng do việc tải về thư viện JavaScript nặng nề. Ví dụ, nếu bạn chỉ cần Ajax hỗ trợ các hàm, bạn chỉ cần tính đến gói Base (Cơ sở); sẽ không có các thành phần giao diện người dùng Dijit mở rộng. Bạn sẽ tìm hiểu thêm về cách Dojo tải các mô đun khác nhau sau trong loạt bài này.
- Gói Cơ sở
- Gói phần mềm Cơ sở (Base) cung cấp nền tảng của bộ công cụ Dojo, bao gồm cả hàm ví dụ như các hàm tiện ích DOM, các tính năng truy vấn DOM dựa trên-bộ chọn CSS3, xử lý sự kiện, Ajax, hình ảnh động cơ bản và các tính năng hướng đối tượng dựa trên-lớp của Dojo. Phần lớn bài này tập trung vào gói Cơ sở.
- Gói Lõi
- Gói phần mềm Lõi (Core) bao gồm một số hàm bổ sung không có trong gói Cơ sở. Nói chung, các tính năng này có xu hướng không được sử dụng quá nhiều như là các hàm do gói Cơ sở cung cấp; do đó, chúng được nạp một cách riêng rẽ để giảm bớt gánh nặng lên gói Cơ sở. Theo cách đó, gói phần mềm Core cung cấp một số thành phần thực sự có ích bao gồm hình ảnh động, kéo và thả, I/O, quản lý dữ liệu, quốc tế hóa (i8n) và quản lý lịch sử trình duyệt nâng cao. Gói phần mềm Core không được trình bày trong bài này.
- Gói Dijit
- Gói phần mềm Dijit bao gồm thư viện giao diện người dùng mở rộng của Dojo về các tiện ích (widget) và các thành phần. Một số ví dụ về các tiện ích bao gồm các hộp thoại, các lịch biểu, các bảng màu, các chú giải công cụ và các cây. Nó cũng bao gồm một tập các nút điều khiển biểu mẫu cung cấp nhiều chức năng hơn so với các nút điều khiển biểu mẫu HTML tiêu chuẩn, cũng như các tùy chọn quản lý bố cục đầy đủ. Phần thứ ba của loạt bài này sẽ mô tả bao quát sâu hơn về gói Dijit.
- Gói DojoX
- Các phần mở rộng Dojo (DojoX) có chứa các dự án con khác nhau của bộ công cụ này. Hầu hết các tính năng thử nghiệm của Dojo nằm trong DojoX, nhưng nó còn chứa nhiều thành phần và các tính năng ổn định. DojoX sẽ được trình bày ngắn gọn trong phần thứ ba của loạt bài này.
Cũng nói đủ chuyện về Dojo rồi. Chúng ta hãy bắt đầu thực sự làm việc với bộ công cụ này. Phần này giải thích các cách sử dụng Dojo khác nhau trong các dự án của bạn, làm thế nào để thiết lập một môi trường phát triển khi sử dụng Firefox và trình cắm thêm Firebug, và cách viết một số mã Dojo để đảm bảo rằng tất cả mọi thứ đang làm việc như mong đợi.
Cách dễ nhất để thiết lập Dojo là dùng nó từ một Mạng phân phối nội dung (CDN- Content Delivery Network), sẽ phân phối các tệp Dojo JavaScript từ một máy chủ gần khách truy cập chứ không phải từ máy chủ riêng của bạn. Không chỉ làm việc này để giúp tăng tốc độ tải kịch bản lệnh, mà việc này còn có nghĩa là có một cơ hội tăng thêm cho người dùng đã tải các tệp Dojo từ một trang web khác rồi, sẽ dẫn đến tải thiết lập Dojo từ bộ nhớ truy cập nhanh (cache), làm tăng nhanh việc thiết lập này lên hơn nữa.
Trong loạt bài này, giả sử rằng bạn đang sử dụng Dojo 1.5, mặc dù bất kỳ
phiên bản 1.x nào cũng sẽ tương thích. Việc gộp thẻ
<script> sau trong trang HTML của bạn sẽ
tải Dojo 1.5 từ CDN của Google:
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js"></script> |
Ngoài ra, bạn có thể tải Dojo về máy chủ riêng của bạn và tải nó từ đó. Phương pháp ưa thích của tôi là tải từ một CDN, nhưng để có một bản dự phòng cục bộ cần một bước nào đó thực hiện sai trên máy chủ CDN. Để làm điều này, tải về Dojo và đặt các tệp vào một chỗ thích hợp có liên quan đến nơi bạn sẽ lưu trữ nội dung web của bạn. Giả sử đường dẫn có liên quan từ nội dung trang web của bạn đến các tệp kịch bản lệnh Dojo là "script/", đoạn mã trong Liệt kê 1 sẽ thử tải Dojo CDN đầu tiên, và nếu không thành công, nó sẽ tải phiên bản cục bộ để thay thế.
Liệt kê 1. Tải Dojo từ CDN có bản dự phòng cục bộ
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js">
</script>
<script>
typeof(dojo) === "undefined" && document.write(unescape('%3Cscript
src="js/libs/dojo-1.5.min.js"%3E%3C/script%3E'))
</script>
|
Điều quan trọng là tất cả mã bắt đầu bằng
typeof(dojo) được đặt trên một dòng duy nhất;
nếu không, nó sẽ không làm việc. Nếu bạn muốn kiểm tra bản dự phòng đang
làm việc, chỉ cần ghi chú dòng tải từ CDN và thử nghiệm trang của bạn với
ví dụ "Hello, World!" (Chào thế giới!) mà bạn sẽ tạo sau đây.
Sử dụng giao diện điều khiển Firebug
Thay vì cần tạo ra một trang web để thử Dojo, nhiều ví dụ trong bài này được thực hiện bằng cách sử dụng một trình cắm thêm Firefox tuyệt vời, đó là Firebug. Firebug cung cấp cho các nhà phát triển JavaScript đầy đủ các phương tiện ghi nhật ký, gỡ lỗi và và theo dõi mạng của giao diện điều khiển, làm cho quá trình thử nghiệm và sửa lỗi trong các ứng dụng JavaScript dễ dàng hơn nhiều. Một số trình duyệt web khác thực sự có các tính năng này, nhưng trong ví dụ này tôi sử dụng Firefox và Firebug do chúng đang có sẵn trên nhiều nền tảng.
Đầu tiên, bạn phải cài đặt Firefox và Firebug (xem Tài nguyên để biết thông tin tải về). Sau khi cài đặt Firefox, khởi động nó rồi tải về và cài đặt trình cắm thêm Firebug. Với Firebug đã cài đặt, bạn sẽ thấy một biểu tượng lỗi như hiển thị trên Hình 1 ở góc phải bên dưới cửa sổ Firefox của bạn. Việc nhấn vào biểu tượng này sẽ mở cửa sổ Firebug.
Hình 1. Biểu tượng và cửa sổ Firebug
Để sử dụng giao diện điều khiển Firebug, nhấn vào thẻ Console (Giao diện
điều khiển). Bạn có thể cần chạy giao diện điều khiển đầu tiên này bằng
cách nhấn vào mũi tên xuống trong thẻ đó và nhấn Enable.
Bây giờ, trong cửa sổ giao diện điều khiển, nhập mã sau đây:
console.log("Test");.
Bạn sẽ thấy một kết quả như trong Hình 2, với một thông báo rằng trình gỡ lỗi JavaScript đang chạy để hỗ trợ giao diện điều khiển này.
Hình 2. Sử dụng giao diện điều khiển Firebug
Tiếp theo, chúng ta hãy chạy thử Dojo. Với ví dụ "Hello, World!", bạn sẽ sử dụng Dojo để đính kèm một hàm khi DOM đã hoàn thành tải dữ liệu (xem Liệt kê 2). Hàm này chỉ đơn giản là in một thông báo "Hello, World!" đến cuối trang. Được rồi, do điều này sẽ không thay đổi chính xác cách bạn tạo các ứng dụng web, nên những gì nó sẽ làm là cho phép bạn chắc rằng Dojo có sẵn trên trang của bạn. Bạn cũng sẽ tải trang này trong suốt bài này để khám phá các tính năng Dojo khi sử dụng giao diện điều khiển Firebug.
Liệt kê 2. listing1.html: ứng dụng Hello World của Dojo
<html>
<head>
<title>Exploring Dojo</title>
</head>
<body>
<h1>Exploring Dojo</h1>
<div id="message">This is a DIV element with id attribute message.</div>
<ul id="list">
<li>This is the first item in a list</li>
<li class="highlight">This is the second item in a list</li>
<li>This is the third item in a list</li>
</ul>
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js">
</script>
<script>
dojo.addOnLoad(function() {
dojo.create(
"div",
{
"innerHTML": "Hello, World!"
},
dojo.body()
);
});
</script>
</body>
</html>
|
Kịch bản lệnh này sẽ đính kèm một hàm anonymous
(ẩn danh) bắt đầu chạy khi DOM đã tải xong. Hàm này sử dụng
dojo.create để xây dựng một phần tử
<div> mới của DOM, thiết lập đặc tính
innerHTML của nó cho "Hello, World!", và chèn
nó vào phần thân của trang bằng cách sử dụng hàm tiện ích
dojo.body. Kết quả này được thể hiện trong Hình
3. Bạn sẽ nhận thấy rằng thông báo "Hello, World!" đã được gắn thêm vào
cuối phần thân của trang.
Hình 3. Trang "Hello, World!" với vẻ đẹp toàn diện của nó
Lúc này đừng xóa trang này hoặc đóng nó. Trong phần tiếp theo, bạn sẽ vẫn sử dụng trang này với mục đích duy nhất để tải Dojo, và bạn sẽ thử một số khía cạnh của Dojo trực tiếp bằng cách sử dụng giao diện điều khiển Firebug.
Trước khi chuyển sang phần tiếp theo, điều quan trọng là chỉ ra một cái gì
đó về vị trí của các JavaScript trên trang này. Bạn có thể nhận thấy rằng
thay vì có cả Dojo và JavaScript của trang trong phần
<head> của tài liệu HTML, tôi đã thêm nó
vào cuối trang, ngay trước phần tử <body>
đóng. Lý do là khi đặt JavaScript ở đó, nó sẽ không chặn các phần tử khác
của trang từ lúc tải. Khi sử dụng các thư viện JavaScript trong trang của
bạn, điều quan trọng là bảo đảm rằng chúng không chặn các phần khác của
trang của bạn từ lúc tải vì thế tối ưu hóa hiệu năng của trang của bạn. Để
biết thêm thông tin về điều này, xem Tài
nguyên.
Trong phần này, bạn sẽ tìm hiểu một số các hàm có ích mà Dojo cung cấp để giúp làm việc với DOM và các mảng dễ dàng hơn. Để thử các ví dụ trong phần này, giữ cho trang mà bạn tạo ra trong phần trước mở trong Firefox và gõ mã được đưa ra vào cửa sổ giao diện điều khiển Firebug.
Các hàm tiện ích DOM giúp làm việc với các phần tử trong DOM dễ dàng hơn bằng cách cung cấp khả năng tìm các mục theo ID của chúng hoặc sử dụng các bộ chọn CSS3. Ngoài ra còn có các hàm để tạo và hủy bỏ các phần tử cũng như để xử lý các nội dung của các phần tử hiện có.
Hàm dojo.byId cho phép bạn chọn một nút DOM theo
thuộc tính id của nó. Hàm này có một bí danh
theo hàm JavaScript chuẩn
document.getElementById nhưng rõ ràng viết ngắn
hơn và cũng quan tâm đến một số mâu thuẫn giữa các trình duyệt. Bây giờ
hãy sử dụng giao diện điều khiển Firebug để đăng nhập vào các nội dung của
phần tử DOM có ID là "message":
dojo.byId("message").innerHTML;.
Ở phía bên trái của giao diện điều khiển, bạn sẽ thấy đáp ứng được hiển thị trong Liệt kê 3.
Liệt kê 3. Đáp ứng
>>> dojo.byId("message").innerHTML;
"This is a DIV element with id attribute message1."
|
Dòng đầu tiên trong Liệt kê 3 chỉ đơn giản lặp lại lệnh đã được ban hành.
Dòng thứ hai là kết quả của lệnh đó, trong trường hợp này, nội dung của
phần tử <h1> có ID là "message".
Trước khi đi tiếp, chúng ta hãy làm vài thứ thú vị hơn một chút. Trong vùng trình soạn thảo của giao diện điều khiển, nhập lệnh được hiển thị trong Liệt kê 4.
Liệt kê 4. Lệnh
dojo.fadeOut
dojo.fadeOut({
node: dojo.byId("message"),
duration: 600
}).play();
|
Bạn sẽ thấy phần tử mờ dần và biến mất khỏi trang. Để nó rõ dần trở lại,
thay đổi giá trị tham khảo fadeOut trong dòng
lệnh thành fadeIn và chạy lại nó. Khá tài tình?
Việc này cho thấy cách bạn có thể thao tác động trang hiện tại bằng cách
sử dụng giao diện điều khiển Firebug. Tất nhiên, những thay đổi này chỉ áp
dụng cho việc tải trang hiện tại và sẽ không được tồn tại lâu bền nếu bạn
chuyển hướng ra xa khỏi trang hoặc làm mới nó.
Trong phần trước, bạn đã học cách nhận được một giá trị tham khảo cho một
phần tử DOM bằng cách sử dụng thuộc tính id của
nó. Bình thường, sẽ không khả thi để thêm thuộc tính này cho mọi phần tử
mà bạn muốn tương tác. Ngoài ra, một id phải là
duy nhất. Vậy điều gì sẽ xảy ra nếu bạn muốn tham khảo một số phần tử cùng
một lúc? Đây là nơi mà hàm dojo.query can
thiệp.
Giả sử bạn muốn lấy một giá trị tham khảo cho tất cả các phần tử con
<li> của danh sách không theo thứ tự có
ID là "list" trong trang của bạn và in ra các nội dung của từng phần tử
này tới giao diện điều khiển. Nhờ hàm
dojo.query, điều này thực sự đơn giản (xem Liệt
kê 5).
Liệt kê 5. Lệnh
dojo.query
dojo.query("#list li").forEach(function(item) {
console.log(item.innerHTML);
});
|
Lệnh này sẽ tạo kết quả đầu ra như trong Liệt kê 6 trong giao diện điều khiển.
Liệt kê 6. Kết quả đầu ra trong giao diện điều khiển
>>> dojo.query("#list li").forEach(function(item) { console.log
(item.innerHTML); });
This is the first item in a list
This is the second item in a list
This is the third item in a list
[li, li.highlight, li]
|
Hàm dojo.query chấp nhận một đối số chuỗi với
một giá trị tham khảo của bộ chọn CSS3 cho các phần tử mà bạn muốn chọn.
Trong trường hợp cụ thể này, bạn sẽ nói rằng bạn muốn chọn tất cả các phần
tử li là phần tử con của phần tử có ID "list".
Hàm này trả về một mảng các phần tử phù hợp với truy vấn. Trong ví dụ ở
Liệt kê 6, bạn sử dụng hàm dojo.forEach để lặp
lại hết mảng này và ghi nhật ký đặc tính
innerHTML của mỗi phần tử được tìm thấy vào
giao diện điều khiển. Bạn sẽ tìm hiểu thêm về hàm này và các hàm mảng khác
trong phần tiếp theo.
Trước khi di chuyển lên, chúng ta hãy sử dụng
dojo.query để tìm bất kỳ phần tử HTML nào có
tên lớp là highlight và áp dụng một số kiểu
dáng để làm cho chúng nổi bật (xem Liệt kê 7).
Liệt kê 7. Sử dụng
dojo.query để tìm bất kỳ phần tử HTML nào có tên lớp là highlight
dojo.query(".highlight").style({
backgroundColor: "yellow",
color: "red"
});
|
Bạn sẽ nhận thấy rằng mục thứ hai trong danh sách không theo thứ tự trên
trang thay đổi sang có một nền màu vàng, với màu văn bản thay đổi thành
màu đỏ. Bạn có thể nhận thấy rằng trong trường hợp này hàm
dojo.forEach đã không được sử dụng. Tôi sẽ
trình bày lý do tại sao hàm này không cần thiết trong phần tiếp theo, "Các mảng và các NodeList."
Ngoài truy vấn DOM và chọn phần tử, có một số hàm tiện ích khác có sẵn
trong Dojo giúp làm việc với DOM dễ dàng hơn nhiều. Bạn đã nhìn thấy một
vài hàm trong số này trong ví dụ "Hello, World". Hàm
dojo.body chỉ đơn giản trả về một giá trị tham
khảo cho phần tử <body> của tài liệu,
dojo.body, và trả về chính đối tượng tài liệu
đó. dojo.create cho phép bạn nhanh chóng tạo ra
một phần tử mới, định nghĩa thuộc tính của nó, và đặt nó trong DOM.
Các hàm khác hiện có bao gồm dojo.place, cho
phép bạn đặt các phần tử hiện tại hoặc mới vào bất cứ nơi nào trong tài
liệu. dojo.empty chính là điều mà bạn mong muốn
ở nó — nó xóa rỗng nội dung của một phần tử DOM.
dojo.destroy loại bỏ một nút, mang theo bất kỳ
phần tử con nào cùng với nó. Để biết thêm thông tin về bất kỳ các hàm này,
xem Tài nguyên để có được một liên kết đến tài
liệu tham chiếu Dojo.
Các mảng cho phép bạn lưu trữ một bộ sưu tập các giá trị và chúng có sẵn
trong tiêu chuẩn JavaScript. Trong Dojo, các mảng được mở rộng để bao gồm
một số hàm trợ giúp. Các mảng mở rộng được gọi là các NodeList. Một
NodeList có thể sử dụng bất kỳ hàm mảng tiêu chuẩn nào cũng như các hàm
Dojo cụ thể bổ sung. Khi bạn sử dụng hàm
dojo.query được mô tả ở phần trước, giá trị trả
về là một đối tượng NodeList (hoặc
dojo.NodeList riêng biệt). Chúng ta hãy xem một
số hàm có sẵn trong các NodeList.
Hàm đầu tiên đáng thảo luận là hàm dojo.forEach
mà bạn đã thấy trong ví dụ dojo.query từ phần
trước của bài này. Hàm này cho phép bạn định nghĩa một trình lặp
(iterator) trên một NodeList, cung cấp một hàm sẽ được áp dụng cho từng
mục trong NodeList. Chúng ta hãy xem một ví dụ cơ bản trong Liệt kê 8.
Liệt kê 8. Ví dụ cơ bản
var list = ['My','name','is','Joe'];
dojo.forEach(list, function(item, i) {
console.log((i+1)+'. '+item);
});
|
Mã trong Liệt kê 8 này sẽ cho kết quả đầu ra được hiển thị trong Liệt kê 9.
Liệt kê 9. Đầu ra
>>> var list = ['My','name','is','Joe']; dojo.forEac...item, i)
{ console.log((i+1)+'. '+item); });
1. My
2. name
3. is
4. Joe
|
Như bạn có thể thấy, hàm forEach lấy từng mục
trong mảng và thực hiện hàm gắn kèm trên nó. Ở trên, bạn đã sử dụng một
hàm anonymous (ẩn danh), nhưng bạn cũng có thể
sử dụng một hàm có tên, như trong Liệt kê 10.
Liệt kê 10. Lặp lại hết một mảng với
dojo.forEach bằng cách sử dụng một hàm có tên
var list = ['My','name','is','Joe'];
var printArray = function(item, i) {
console.log((i+1)+'. '+item);
}
dojo.forEach(list, printArray);
|
Hàm dojo.indexOf cho phép bạn tìm thấy vị trí có
một giá trị cụ thể trong một mảng. Cách tốt nhất để minh họa nó là dùng ví
dụ. Sử dụng mảng danh sách được tạo ra trong phần trước, thử tính toán chỉ
mục của mảng có giá trị name ở trong:
dojo.indexOf(list, "name");.
Hàm này trả về kết quả được hiển thị trong Liệt kê 11.
Liệt kê 11. Kết quả
>>> dojo.indexOf(list, "name"); 1 |
Do đó giá trị name có chỉ mục là 1 trong mảng
này. Hãy nhớ rằng các mảng JavaScript bắt đầu từ chỉ mục là 0, nên giá trị
này là mục thứ hai trong mảng. Nếu bạn cố gắng sử dụng hàm này khi cung
cấp một giá trị không còn trong mảng nữa, giá trị trả về là
-1.
Hàm này trả về chỉ mục đầu tiên được tìm thấy với giá trị đã cho, vì vậy
nếu có nhiều mục trong mảng có cùng một giá trị, hàm này sẽ dừng lại ở mục
đầu tiên. Dojo cung cấp một hàm tương tự,
dojo.lastIndexOf, cho phép bạn tìm chỉ mục cuối
cùng của một giá trị cụ thể. Hàm này hoạt động theo cách chính xác tương
tự như dojo.indexOf.
Hàm dojo.filter cho phép bạn tạo một mảng mới là
một phiên bản được lọc của mảng khác. Ví dụ, nếu bạn muốn tạo một phiên
bản mới của mảng danh sách mà bạn tạo ra trước đó, nhưng loại trừ bất kỳ
các mục có giá trị is, bạn có thể sử dụng đoạn
mã được hiển thị trong Liệt kê 12.
Liệt kê 12. Lọc một mảng để tạo ra một mảng mới
var filteredList = dojo.filter(list, function(item) {
return item != "is";
});
dojo.forEach(filteredList, "console.log(item)");
This results in the following output:
>>> var filteredList = dojo.filter(list,
function(it...dojo.forEach(filteredList, "console.log(item)");
My
name
Joe
|
Dojo có chứa một vài hàm NodeList khác rất có ích khi làm việc với các
mảng. Hàm dojo.map cho phép bạn tạo ra một mảng
mới là một phiên bản sửa đổi của một mảng hiện có. Ví dụ, bạn có thể có
một mảng các số biểu thị các giá trị tiền tệ. Bạn có thể sử dụng một hàm
ánh xạ để trả về một mảng các giá trị này theo một định dạng tiền tệ.
dojo.some cho phép bạn kiểm tra xem ít nhất một
mục trong một mảng có phù hợp với tiêu chuẩn đã quy định không. Tương tự,
dojo.every được sử dụng để kiểm tra xem tất cả
các mục trong một mảng có phù hợp với tiêu chuẩn quy định không. Để có một
danh sách đầy đủ các hàm NodeList và tài liệu liên kết của chúng, xem Tài nguyên.
Hầu hết các thư viện JavaScript có một công cụ xử lý sự kiện JavaScript nguyên gốc giữa các trình duyệt, cho phép bạn đính kèm các hàm được gọi khi một sự kiện DOM được kích hoạt. Rất tiện lợi, Dojo mang khái niệm này tiến một bước xa hơn bằng cách cho phép bạn kết nối các hàm với các hàm khác, có thể là các sự kiện DOM, các sự kiện đối tượng, các hàm do người dùng định nghĩa, hoặc "các chủ đề," được thảo luận sau trong phần này.
Cách đầu tiên gắn các hàm với các sự kiện DOM là sử dụng hàm
dojo.connect. Cách tốt nhất để minh họa điều
này là dùng ví dụ. Trong giao diện điều khiển Firebug, nhập mã trong Liệt
kê 13.
Liệt kê 13. Gắn các hàm với các sự kiện DOM khi sử dụng
dojo.connect
var message = dojo.byId("message");
dojo.connect(message, "onclick", function() {
alert(message.innerHTML);
});
|
Điều này dẫn đến kết quả đầu ra như ở Liệt kê 14 trong giao diện điều khiển.
Liệt kê 14. Đầu ra
>>> var message = dojo.byId("message"); dojo.connect..., function()
{ alert(message.innerHTML); });
[div#message, "onclick", function(), 1]
|
Điều đó là tuyệt vời và tất cả, những không phải hàm này thực sự làm một
cái gì đó chứ? Chắc chắn rồi. Dojo đã kèm theo một hàm cho trình xử lý sự
kiện click của phần tử có ID "message". Để thử
nghiệm nó, hãy nhấn vào thông báo trên màn hình với nội dung "This is a
DIV element with id attribute message" (Đây là một phần tử DIV có thông
báo thuộc tính id). Bạn sẽ thấy một hộp cảnh báo JavaScript, như thể hiện
trong Hình 4.
Hình 4. Gắn các hàm cho các sự kiện DOM
Đẹp và dễ dàng, có phải không? Điều gì sẽ xảy ra nếu bạn muốn đính kèm một sự kiện cho tất cả các mục trong một mảng? Ví dụ, chúng ta nói bạn muốn mỗi mục trong danh sách không theo thứ tự trên trang của bạn làm nổi bật bằng in đậm khi bạn nhấn vào chúng. Bạn có thể dễ dàng làm điều này với mã trong Liệt kê 15.
Liệt kê 15. Gắn các sự kiện vào một mảng các phần tử
dojo.query("#list li").forEach(function(item) {
dojo.connect(item, "onclick", function() {
dojo.style(item, {
fontWeight: "bold"
});
});
});
|
Hãy thử nó, nó hoạt động. Dojo cho phép bạn viết đoạn mã này theo cách còn
ngắn gọn hơn. Thay vì sử dụng forEach để lặp
qua mảng, để thay thế bạn có thể sử dụng một hàm phím tắt
NodeList.connect để làm điều đó, như trong Liệt
kê 16.
Liệt kê 16. Gắn các sự kiện vào một mảng các phần tử (được cải thiện)
dojo.query("#list li").onclick(function(e) {
dojo.style(e.target, {
fontWeight: "bold"
});
});
|
Bởi vì bạn đã gắn một sự kiện vào danh sách rồi, bạn nên làm mới trang
trước khi thử mã trong Liệt kê 16 để đảm bảo nó sẽ hoạt động. Đối số
e là một giá trị tham khảo cho đối tượng
Event (sự kiện), và đặc tính
target (mục tiêu) của đối tượng này để cho bạn
nhận biết phần tử đã bắt đầu thực hiện sự kiện. Bạn sử dụng nó để nhận
biết phần tử nên được áp dụng kiểu dáng in đậm. Hãy thử nhấn vào ba mục
danh sách, mỗi mục trong đó sẽ trở thành in đậm sau khi bạn nhấn vào
chúng.
Kết nối các hàm với các hàm khác
Trong các ví dụ trước, bạn đã kết nối các hàm với các sự kiện DOM. Dojo
cũng cho phép bạn kết nối các hàm với các hàm khác theo cách tương tự. Một
ví dụ về điều này có thể là một hàm cho thấy một hình ảnh bánh xe quay ở
đâu đó trên trang của bạn. Khi người dùng thực hiện một hàm Ajax, bạn muốn
hiển thị hình ảnh này. Cũng vậy, khi hàm này đã trả về một đáp ứng, bạn
muốn ẩn đi hình ảnh này. Nếu không sử dụng
dojo.connect, mã của bạn có thể trông như Liệt
kê 17.
Liệt kê 17. Kết nối các hàm với các hàm khác mà không dùng
dojo.connect
function toggleImage() {
//Code to show/hide loading image goes here
}
function callAjax() {
toggleImage();
//Code to call Ajax function goes here
}
function handleResponse() {
//Code to handle Ajax response goes here
toggleImage();
}
|
Trong khi không có bất kỳ lỗi nào với mã này, cuộc gọi hàm
toggleImage được ấn định trong cả hai hàm
callAjax và
handleResponse. Nếu bạn muốn bổ sung thêm một
cuộc gọi hàm khác, bạn sẽ phải thay đổi các hàm này một lần nữa để có các
cuộc gọi thêm. Thay vào việc thêm cuộc gọi hàm tới chính các hàm này, bạn
có thể sử dụng dojo.connect để thiết lập liên
kết giữa chúng. Liệt kê 18 cho thấy phương thức
dojo.connect có thể trông như thế nào.
Liệt kê 18. Kết nối các hàm với các hàm khác dùng
dojo.connect
function toggleImage() {
//Code to show/hide loading image goes here
}
function callAjax() {
//Code to call Ajax function goes here
}
function handleResponse() {
//Code to handle Ajax response goes here
}
dojo.connect(callAjax, toggleImage);
dojo.connect(handleResponse, toggleImage);
|
Kiểu dáng mã hóa này có thể không là hương vị của mỗi nhà phát triển, nhưng nó cho phép bạn tổ chức mã của bạn theo cách cho dễ đọc hơn nhiều.
Xuất bản và đăng ký các chủ đề
Khía cạnh cuối cùng về xử lý sự kiện Dojo đáng nói đến là khả năng xuất bản
và đăng ký theo các chủ đề. Điều này cho phép các thành phần Dojo tương
tác với nhau, ngay cả khi chúng không biết về sự tồn tại của nhau. Ví dụ,
chúng ta nói rằng bạn đã định nghĩa một chủ đề có tên là
printName, hy vọng một đối tượng
message có tên và họ của cá nhân. Bạn có thể có
một thành phần đăng ký theo chủ đề này, sẽ in tên vào giao diện điều khiển
bất cứ lúc nào có một thành phần khác xuất bản theo chủ đề này có tên cá
nhân. Liệt kê 19 cho thấy một ví dụ của một đăng ký như vậy (cứ tự nhiên
thử nó trong Firebug).
Liệt kê 19. Đăng ký
dojo.subscribe("printName", function(msg) {
console.log("The person's name is: "+msg.first_name+" "+msg.last_name);
});
|
Để xuất bản theo chủ đề này, bạn cần phải vượt qua một mảng các đối tượng tuân thủ các API của chủ đề (trong trường hợp này, các đối tượng phải có một tên và họ). Liệt kê 20 là một ví dụ.
Liệt kê 20. Xuất bản theo một chủ đề
dojo.publish("printName", [
{
first_name: "Joe",
last_name: "Lennon"
}
]);
|
Việc này tạo ra kết quả được hiển thị trong Liệt kê 21.
Liệt kê 21. Đầu ra
>>> dojo.publish("printName", [ { first_name: "Joe", last_name: "Lennon" } ]);
The person's name is: Joe Lennon
|
Như bạn có thể thấy, bằng việc xuất bản đối tượng này theo chủ đề
printName, hàm đã đăng ký của bạn xuất ra một
thông báo tương ứng với giao diện điều khiển.
Trao quyền cho Ajax bằng dojo.xhr*
Việc tạo các ứng dụng web có trang bị Ajax thường được thực hiện bằng cách
tạo một đối tượng XmlHttpRequest
(XHR) đối tượng này sẽ tạo ra một yêu cầu HTTP
với một địa chỉ URL cụ thể, chuyển qua một tiêu đề và phần thân của yêu
cầu, và định nghĩa các hàm gọi lại để xác định những gì nên được thực hiện
khi đáp ứng trả về với một phần thân đáp ứng thành công hay một đáp ứng
HTTP thất bại. Việc thực hiện các XHR giữa các trình duyệt có thể nói ít
nhất là rất chán, nhưng, may mắn thay, Dojo làm dịu đáng kể nỗi đau đó
bằng một tập các hàm dojo.xhr* cho phép bạn
thực hiện các yêu cầu GET,
POST, PUT và
DELETE.
Bốn hàm được cung cấp như sau:
xhrGetxhrPostxhrPutxhrDelete
Tất cả các hàm này theo cú pháp như nhau: chấp nhận một đối tượng cấu hình đặc tính đơn lẻ làm một đối số. Trong đối tượng này, bạn có thể định nghĩa các khía cạnh khác nhau của yêu cầu Ajax mà bạn muốn thực hiện. Một lần nữa, các tùy chọn này đều giống nhau trên tất cả các hàm XHR.
Một số các tùy chọn cấu hình có ích có sẵn cho các hàm
XHR như sau:
url- Đây là địa chỉ URL mà yêu cầu HTTP cần được thực hiện. Nó phải nằm trong cùng miền và cùng cách kết hợp cổng như trang đang thực hiện yêu cầu này.
handleAs- Cho phép bạn định nghĩa định dạng mà đáp ứng cần được xử lý. Mặc định
là
text, nhưng cũng có sẵnjson,javascript,xmlvà một vài tùy chọn khác. Bạn sẽ thấy một ví dụ về tạo một yêu cầu Ajax với một hàm gọi lại để xử lý một định dạng đáp ứng JSON sau trong phần này. form- Hoặc là một giá trị tham khảo đến hoặc biểu diễn chuỗi ID của một phần
tử
<form>. Các giá trị của từng trường theo biểu mẫu này sẽ được gửi đi cùng với yêu cầu như phần thân của yêu cầu. content- Một đối tượng có chứa các tham số mà bạn muốn chuyển tài nguyên vào
phần thân của yêu cầu. Đối tượng này sẽ được trộn lẫn với các giá trị
được lấy từ đặc tính
formnếu cả hai được cung cấp.
Một ví dụ về một hàm XHR được hiển thị trong
Liệt kê 22.
Liệt kê 22. Ví dụ về một cuộc gọi hàm XHR
dojo.xhrGet({
url: "save_data.php",
content: {
id: "100",
first_name: "Joe",
last_name: "Lennon"
}
});
|
Hàm này sẽ tạo không đồng bộ một yêu cầu HTTP
GET đến tệp save_data.php trong cùng một vị trí
như chính tài liệu đó. Nó sẽ chuyển các đặc tính của đối tượng nội dung
tới kịch bản lệnh PHP làm các tham số. Trong PHP, sau đó bạn sẽ sử dụng
biến $_GET để lấy ra các giá trị này và có thể
lưu chúng vào một cơ sở dữ liệu.
Trong ví dụ trước, bạn đã học cách để bạn có thể gọi một yêu cầu Ajax bằng
dojo.xhrGet. Trong khi ví dụ đã đủ để thực sự
đưa ra yêu cầu, nó đã không cung cấp phương tiện nào để xử lý bất kỳ đáp
ứng nào. Các hàm gọi lại cũng được truyền tới đối tượng cấu hình. Các tùy
chọn sau đây có sẵn:
load- Hàm này sẽ được thực hiện khi một yêu cầu Ajax trả về một thông báo đáp ứng thành công. Các dữ liệu đáp ứng và đối tượng yêu cầu được chuyển tới hàm này làm các đối số.
error- Hàm này sẽ được thực hiện nếu có một vấn đề với yêu cầu Ajax. Hàm này có thể xảy ra nếu địa chỉ URL được chỉ rõ trong yêu cầu Ajax là không hợp lệ, nếu yêu cầu tạm dừng, hoặc nếu xảy ra một số lỗi HTTP khác. Thông báo lỗi và đối tượng yêu cầu được chuyển làm các đối số.
handle- Hàm này cho phép bạn kết hợp các hàm gọi lại tải và lỗi vào một hàm duy nhất (có ích nếu bạn thực sự không quan tâm xem này yêu cầu dẫn đến thành công hay lỗi không).
Trong ví dụ tiếp theo, bạn sẽ tạo ra một cuộc gọi Ajax với một hàm gọi lại tải, sẽ tải một số dữ liệu từ một tệp JSON và in nó lên trang này.
Hãy đặt các hàm dojo.xhr* vào một bài thử nghiệm
tốt hơn bằng cách tạo ra một ví dụ thực tế hơn. Đầu tiên, tạo một tệp mới
— đặt tệp này trong cùng thư mục như tệp listing1.html
— và thêm một số dữ liệu JSON vào nó. Các nội dung của
tệp được hiển thị trong Liệt kê 23.
Liệt kê 23. data.json — một yêu cầu Ajax xử lý dữ liệu JSON
{
count: 4,
people: [
{
first_name: "Joe",
last_name: "Lennon",
age: 25
},{
first_name: "Darragh",
last_name: "Duffy",
age: 33
},{
first_name: "Jonathan",
last_name: "Reardon",
age: 30
},{
first_name: "Finian",
last_name: "O'Connor",
age: 23
}
]
}
|
Bây giờ tạo một yêu cầu Ajax trong Firebug (chắc chắn rằng trang
listing1.html được nạp vào Firefox để cho Dojo được tải). Yêu cầu này sử
dụng hàm gọi lại load để xử lý đáp ứng JSON và
in một bảng lên trang này (xem Liệt kê 24).
Liệt kê 24. Sử dụng Ajax để tải và xử lý dữ liệu JSON
dojo.xhrGet({
url: "data.json",
handleAs: "json",
load: function(data) {
var table = "<table border=\"1\">";
table += "<tr><th>Name</th><th>Age</th>
</tr>";
dojo.forEach(data.people, function(person) {
table += "<tr><td>";
table += person.first_name+" "+person.last_name;
table += "</td><td>";
table += person.age;
table += "</td></tr>";
});
table += "</table>";
dojo.place(table, dojo.body());
}
});
|
Hãy thử mã được hiển thị trong Liệt kê 24 trong Firebug. Nên thêm động một bảng vào trang của bạn với dữ liệu được nạp từ tệp JSON. Việc này được thể hiện trong Hình 5.
Hình 5. Bảng có tải Ajax từ dữ liệu JSON
Trong một ví dụ thế giới thực, bạn sẽ sử dụng một ngôn ngữ phía máy chủ như PHP, Python, ASP.NET hoặc Java để tạo dữ liệu JSON động dựa trên các tham số được truyền cho nó bằng yêu cầu Ajax.
Trong phần này của loạt bài Dojo từ dưới lên, bạn đã tìm hiểu về Dojo và các điều cơ bản về cách sử dụng nó. Đặc biệt, bạn đã tìm hiểu về các hàm tiện ích DOM khác nhau, các hàm mảng, xử lý sự kiện và các tính năng XHR. Trong phần tiếp theo của loạt bài này, bạn sẽ tìm hiểu cách sử dụng các tính năng hướng đối tượng dựa vào lớp như-Java™ của Dojo.
| Mô tả | Tên | Kích thước | Phương thức tải |
|---|---|---|---|
| Article source code | dojo.ground.1.zip | 1KB | HTTP |
Học tập
- Truy cập trang chủ để biết Bộ công cụ Dojo.
- Xem một số Trình diễn về Bộ công cụ
Dojo.
-
Giới thiệu Bộ công cụ Dojo: Đọc giới thiệu thú vị về Bộ công cụ
Dojo từ trang web của nhà phát triển Opera.
-
Giới thiệu về bộ công cụ Dojo, Phần 1: Thiết lập, lõi, và các tiện
ích: Đọc một giới thiệu thú vị khác về bộ công cụ Dojo từ
JavaWorld.
-
Dojo 1.5: Sẵn sàng cung cấp ứng dụng web của bạn: Tìm hiểu về một
số tính năng mới trong Dojo 1.5 của bài viết này trên Sitepen.
-
Giới thiệu bộ công cụ Dojo: Hướng dẫn: Đọc một hướng dẫn giới
thiệu từ các Ajax Matter.
- "Quốc
tế
hóa các ứng dụng web bằng cách sử dụng Dojo" (developerWorks, 08.
2008): Khám phá một cách thực hiện hỗ trợ ngôn ngữ bản địa trong ngữ cảnh
của các trang web và các ứng dụng web bằng cách sử dụng tính năng i18n của
bộ công cụ Dojo.
- "Sử
dụng dịch vụ web với Bộ công cụ Dojo" (developerWorks, 09.2010):
Tìm hiểu cách dùng các dịch vụ bằng cách sử dụng Bộ công cụ Dojo để chạy
Ajax trên một trang web.
- Hãy xem Dojo: Sử dụng thư viện Dojo JavaScript để xây dựng các ứng dụng
Ajax của James E. Harmon.
- "Viết một ứng dụng Dojo tùy chỉnh"(developerWorks, 12.2008): Tìm
hiểu nhiều hơn về Dojo trong bài viết này của developerWorks.
- "Phát triển các widget HTML với Dojo" (developerWorks, 10.2006)
khám phá khả năng mở rộng của Dojo.
- "Sử dụng Bộ công cụ Dojo với WebSphere Portal"(developerWorks, 11.
2007) mô tả cách cài đặt, cấu hình, sử dụng và tận dụng bộ công cụ Dojo
trong các ứng dụng WebSphere Portal.
-
Vùng phát triển Web
của developerWorks chuyên về các bài viết trình bày các giải pháp dựa trên
web khác nhau.
Lấy sản phẩm và công nghệ
- Tải về Bộ công cụ Dojo. Trong bài
viết này đã sử dụng phiên bản 1.5.
- Truy cập Tài liệu API Toolkit của Dojo.
- Nhận Firefox.
- Nhận Firebug.
-
Ví dụ mở rộng IBM - Dojo: Tập tính năng mở rộng Dojo có thể được
sử dụng để cho phép một mô hình IBM WebSphere Portlet Factory tận dụng
chức năng do Bộ công cụ JavaScript của Dojo cung cấp.
- Tải về các phiên bản đánh giá sản phẩm của IBM và lấy các công cụ phát
triển ứng dụng thực hành của bạn và các sản phẩm phần mềm trung gian từ
DB2®, Lotus®, Rational®,
Tivoli® và WebSphere®.
Thảo luận
- Tạo hồ sơ My developerWorks của bạn hôm nay và thiết lập một danh sách theo dõi trên Dojo. Kết nối và theo sát
kết nối với My developerWorks.
- Tìm các thành viên developerWorks khác quan tâm đến phát triển
web.
- Chia sẻ những gì bạn biết: Tham gia vào một trong các nhóm developerWorks của chúng tôi tập
trung vào các chủ đề web.
- Roland Barcia nói về Web 2.0 và phần mềm trung gian trong blog của mình.
- Làm theo đánh dấu trang có chia sẻ về các chủ đề web của các thành viên
developerWorks.
- Nhận các câu trả lời nhanh chóng: Truy
cập Diễn đàn về ứng dụng Web 2.0.
Joe Lennon là một nhà phát triển phần mềm 24 tuổi đến từ Cork, Ireland. Joe là tác giả của cuốn sách Beginning CouchDB, (Khởi đầu với CouchDB) do Apress sắp xuất bản, và đã đóng góp một số bài viết và hướng dẫn kỹ thuật cho developerWorks IBM. Trong lúc rảnh rỗi, Joe thích chơi bóng đá (soccer), lang thang với các tiện ích, và làm việc trên gamerscore Xbox 360 của mình. Có thể liên hệ với ông qua trang Web của ông tại địa chỉ www.joelennon.ie