Thứ Bảy, 25 tháng 4, 2015

Hello DOJO!

Chào mừng bạn đến với Dojo! Trong bài hướng dẫn này, bạn sẽ học được cách làm thế nào để tải Dojo và bắt đầu khám phá một số chức năng chính của Dojo. Bạn cũng sẽ được học về nền tảng kiến trúc AMD của Dojo, khám phá cách tải những Module bổ sung để thêm các chức năng mở rộng cho Website hoặc ứng dụng của bạn cũng như tìm kiếm giải pháp khi gặp lỗi.

Getting Started - Bắt đầu

Bắt đầu với Dojo thật đơn giản bằng cách đưa tệp dojo.js vào trang web của bạn, giống như những tệp JavaScript khác vậy. Dojo có thể chạy  trên hầu hết các CDNs (mạng phân phối nội dung), vì vậy để bắt đầu ta chỉ việc thêm một tệp hellodojo.html rồi mở nó ra và gõ nội dung dưới đây vào.
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Tutorial: Hello Dojo!</title>
</head>
<body>
    <h1 id="xinChao">Hello</h1>
    <!-- tải Dojo -->
    <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js"
            data-dojo-config="async: true"></script>
</body>
</html>
Thông thường, bạn phải tải thư viện JavaScript để có thể sử dụng tất cả các phương thức cần thiết. Điều này đúng với những phiên bản cũ của Dojo, nhưng từ bản Dojo 1.7 trở đi  Asynchronous Module Definition (AMD) (Khai báo module bất đồng bộ) đã cho phép module hóa hoàn toàn trong việc phát triển ứng dụng web. AMD được chọn bởi vì nó làm việc với mã thuần Javascript, cho phép mã nguồn làm việc trên trình duyệt web, đồng thời cũng hỗ trợ trong việc xây dựng xử lý để sản xuất tối ưu hóa mã nguồn nhằm nâng cao hiệu suất mã nguồn trong quá trình triển khai.
Vậy thì thứ gì là sẵn có khi file <dojo.js> được nạp ?
Đó là Dojo's AMD và khai báo hai hàm toàn cục bằng việc sử dụng 2 lệnh <require> và <define>. Để hiểu thêm chi tiết về AMD, mời bạn đọc bài này . Để bắt đầu, cần hiểu rằng <require> cho phép bạn tải những module và dùng chúng, trong khi <define> cho phép bạn khai báo module của chính bạn. Một module thường là một tệp Javascript đơn.

Một vài module cơ bản của Dojo cho việc tương tác với HTML DOM là <dojo/dom> và <dojo/dom-construct>. Hãy xem cách làm thế nào để tải những module này và dùng các chức năng mà chúng cung cấp:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Tutorial: Hello Dojo!</title>
</head>
<body>
    <h1 id="xinChao">Hello</h1>
    <!-- tải Dojo -->
    <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js"
            data-dojo-config="async: true"></script>

    <script>
        require([
            'dojo/dom',
            'dojo/dom-construct'
        ], function (dom, domConstruct) {
            var xinChaoNode = dom.byId('xinChao');
            domConstruct.place('_ Dojo!_', xinChaoNode);
        });
    </script>
</body>
</html
Tham số đầu tiên để <require>(tại dòng 14-17) là một mảng các định danh module - các định danh cho những modules mà bạn muốn nạp. Nói chung, ở đây ta sẽ liên kết trực tiếp đến tên của tệp, còn nếu bạn tải từ trang phân phối của Dojo và tìm trong thư mục dojo, bạn sẽ thấy 2 tệp dom.js và dom-construct.js như khai báo các modules ở trên.
Trình nạp AMD thực thi bất đồng bộ, và trong JavaScript thì bất đồng bộ thực thi với các callbacks, như tham số thứ hai <require> (dòng 17) là một hàm callback. Trong hàm này, bạn đã cung cấp các modules cho nó sử dụng. Trình nạp AMD gán các modules vào cho hàm như là các tham số (theo thứ tự mà chúng được chỉ định khai báo trong mảng định danh module). Bạn có thể tự đặt tên cho các tham số trong hàm callback của bạn theo ý muốn, nhưng để cho nhất quán và dễ đọc chúng ta nên sử dụng tên cơ bản trên từng định danh module.
Trên dòng 18 và 19, bạn có thể thấy hai modules <dom> và <dom-construct> được dùng để tham chiếu đến một DOM node bằng Id của nó và thao tác với nội dung của DOM node đó.
Trình nạp AMD sẽ tự nạp tất cả các phần liên quan cho một module được yêu cầu, do đó, bạn chỉ nên đưa những modules mà bạn cần sử dụng trực tiếp vào trong danh sách liên quan (để tránh việc trang web của bạn phải tải cả những module bạn không cần dùng).

Define AMD Modules - Khai báo các module AMD

Tại thời điểm này bạn đã nhìn thấy một ví dụ về việc tải và sử dụng các modules. Để khai báo và nạp các modules của chính mình, bạn sẽ cần phải đảm bảo rằng bạn đang tải tập tin HTML của mình từ một máy chủ HTTP (localhost thì ổn nhưng bạn cần một máy chủ HTTP được bảo mật để ngăn chặn các nguy cơ do làm việc với giao thức "file:///"). Với các ví dụ ở đây, bạn không cần quan tâm bất kỳ một chức năng nào trong web server ngoài việc cung cấp tệp tin. Thêm một thư mục <demo> trong thư mục chứa tệp tin <hellodojo.html>, và trong thư mục <demo>, ta tạo một tệp tên là <myModule.js>

hellodojo.html
demo/myModule.js

Bây giờ, điền các nội dung sau vào <myModule.js>

define([
    //Module <dojo/dom> được yêu cầu nên nó sẽ nằm trong danh sách tham số
    'dojo/dom'
], function(dom){
    // Một khi tất cả các module trong danh sách tham số đã tải thì hàm function sẽ được gọi để khai báo module demo/myModule
    //
    // Module <dojo/dom> được thông qua như một đối số đầu tiên cho hàm function, các module sau đó cũng lần lượt được thông qua theo danh sách đối số.

    var oldText = {};

    //Đối tượng được trả về sẽ trở thành giá trị của hàm function
    return {
        setText: function (id, text) {
            var node = dom.byId(id);
            oldText[id] = node.innerHTML;
            node.innerHTML = text;
        },

        restoreText: function (id) {
            var node = dom.byId(id);
            node.innerHTML = oldText[id];
            delete oldText[id];
        }
    };
});
Chức năng <define> trong AMD chấp nhận các tham số như chức năng <require> - nghĩa là, một mảng các định danh modules và một hàm callback. Bộ nạp AMD lưu giữ giá trị trả về của hàm callback như giá trị của mô-đun, vì vậy bất kỳ đoạn mã khác mà nạp mô-đun với <require> (hoặc <define>) sẽ nhận được một tham chiếu đến các giá trị trả lại của các mô-đun được xác định.

CDN Usage - CÁCH SỬ DỤNG CDN

Nạp các modules cục bộ trong khi dùng Dojo từ CDN yêu cầu thêm một số cấu hình (để biết thêm thông tin khi cấu hình trình tải AMD của Dojo và dùng nó với CDN có thể tìm thấy trong bài viết thiết lập AMD Advanced AMD và bài viết dùng Mudule với một CDN ). Nâng cấp tệp <hellodojo.js> như dưới đây:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
    <title>Tutorial: Hello Dojo!</title>
</head>
<body>
<h1 id="xinChao">Hello</h1>
<!-- Cấu hình Dojo -->
<script>
//thay vì dùng data-dojo-config, chúng ta đang tạo một đối tượng cấu hình dojo (dojoConfig) trước khi tải dojo.js
//thực ra chúng giống hệt nhau, chỉ là đơn giản hơn để học cách tiếp cận với những cấu hình lớn hơn.
var dojoConfig = {
async : true,
//Dòng mã này đăng ký vị trí chính xác của một packages "demo" để có thể tải Dojo từ CDN trong khi vẫn đang nạp module cục bộ
packages:[{
name: "demo",
location: location.pathname.replace(/\/[^/]*$/,'')+'/demo'
}]
};
</script>
<!--Load Dojo-->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.3/dojo/dojo.js"></script>

<script>
require(['demo/myModule'], function (myModule){
myModule.setText('xinChao','Hello Dojo!');
setTimeout (function(){
myModule.restoreText('xinChao');
},3000)
});
</script>
</body>
</html>

Ngoài việc thêm cấu hình cho Dojo, chúng ta đã định nghĩa lại main code (mã chính) - bây giờ chỉ tải duy nhất "demo/myModule", và sử dụng nó để hoàn thiện thao tác của văn bản trên trang. Như bạn có thể thấy, khai báo và nạp module thật đơn giản. Chúng ta cũng thay đổi URL để <dojo.js> bỏ qua giao thức HTTP (dòng 24) - nó tạo một liên kết sẽ dùng bất cứ giao thức nào mà trang đang sử dụng (http hoặc https), trong mộ số trình duyệt sẽ có sự cảnh báo an ninh để ngăn chặn nội dung được kết hợp này.

Tổ chức mã trong các modules AMD cho phép bạn tạo tài nguyên một cách module hóa JavaScript ngay từ khi nó được thực thi trên trình duyệt của bạn, và dễ dàng để gỡ lỗi hơn. Các modules AMD dùng trong phạm vi cục bộ cho các biến, tránh lộn xộn các biến toàn cục trong các không gian tên và cung cấp độ phân giải tên nhanh hơn. AMD là một đặc điểm kỹ thuật tiêu chuẩn với nhiều sự triển khai, vì vậy bạn không bị bó buộc vào bất cứ cách triển khai duy nhất nào đó - các modules AMD có thể được dùng với bất cứ trình nạp AMD nào.

Waiting for the DOM - Chờ đợi cho đến khi nạp xong DOM

Một trong những điều phổ biến mà bạn cần phải thực hiện với các ứng dụng web là để đảm bảo rằng DOM của trình duyệt có sẵn trước khi thực hiện mã. Nó thực hiện qua module AMD đặc biệt  có tên  là "plugin" (trình cắm/phụ tùng :v) . Các plugins có thể được yêu cầu như bất cứ một module nào khác nhưng các chức năng đặc biệt của chúng chỉ thực hiện bởi việc thêm dấu chấm than "!" khi kết thúc việc xác định một module. Trong trường hợp sự kiện DOM đã sẵn sàng, Dojo cung cấp plugin <dojo/domReady>. Đơn giản, ta chỉ cần <include> plugin này như một phần phụ thuộc vào bất kỳ lệnh gọi <require> hoặc <define> và hàm callback sẽ không được phát sinh cho đến khi DOM đã sẵn sàng
require([
    'dojo/dom',
    'dojo/domReady!'
], function (dom) {
    var xinChao = dom.byId('xinChao');
    xinChao.innerHTML += ' from Dojo!';
});
Xem ví dụ ở đây: http://jsfiddle.net/5nkopbb1/1/light/

Ví dụ trên đơn giản là thêm một số văn bản vào phần tử <xinChao> - những điều đó chỉ có thể được thực hiện một khi DOM đã được nạp xong (chúng ta đã không sử dụng điều này trong các đoạn mã trước, những lúc mà thẻ <script> nằm dưới cùng trong thẻ <body> - điều này sẽ hoãn việc xử lý của các script cho đến khi DOM được nạp xong). Một lần nữa, lưu ý rằng các định danh mô-đun kết thúc với dấu chấm than "!"; không có điều này, module dojo/domReady sẽ chỉ đơn giản là chức năng giống như bất kỳ thành phần nào khác.

Trong một số trường hợp, tương tự như module <dojo/domReady>, chúng ta chỉ nạp một module cho việc tạo hiệu ứng trang và không cần tham chiếu tới nó. Trình tải AMD không biết điều này - tức là nó luôn thông qua các tham chiếu cho mỗi module trong mảng phụ thuộc đến hàm callback, vì vậy những modules nào của bạn không cần phải sử dụng chúng thì nên đặt chúng ở cuối cùng của mảng các phần phụ thuộc, và hàm callback sẽ bỏ qua chúng trong danh sách tham số.

Để biêt thêm thông tin trong chức năng thao tác DOM, bạn có thể tìm thấy trong hướng dẫn các chức năng của Dojo DOM Functions (http://dojotoolkit.org/documentation/tutorials/1.10/dom_functions/)

Adding Visual Effects - Thêm các hiệu ứng trực giác

Bây giờ chúng ta có thể phấn khởi lên bởi các ví dụ của chúng ta có thêm một vài hiệu ứng hình ảnh. Một module giúp chúng ta có thể tạo hiệu ứng cho trang web đó là <dojo/fx>. Hãy cùng thêm một hiệu ứng trượt vào thành phần xinChao với phương thức <slideTo> của <dojo/fx>:
require(['dojo/dom','dojo/fx','dojo/domReady!'],function(dom,fx){
//Một thành phần chúng ta có trước đây...
var xinChao = dom.byId('xinChao');
xinChao.innerHTML+=' from Dojo';

//...Nhưng bây giờ, cùng với hiệu ứng động!
fx.slideTo({
node: xinChao,
top: 100,
left: 200
}).play();
});

Xem ví dụ ở đây:

Như bạn thấy, chúng ta đã thêm một thành phần phụ thuộc với <dojo/fx> ở từ khóa <require>, sau đó dùng module này để chạy hiệu ứng trong phần tử <xinChao> của mình
Để biết thêm chi tiết về hiệu ứng hay các hình ảnh động, bạn hãy tham khảo tại Dojo EffectAninmations

Using the Dojo Source - Sử dụng tài nguyên Dojo

CDNs thật là tiện dụng. Chúng ta dùng chúng trong ví dụ hướng dẫn, bởi vì điều đó có nghĩa là ta chỉ cần copy trực tiếp mã và không có sự thay đổi bất cứ điều gì để chúng làm việc cho bạn. Tuy nhiên chúng có vài nhược điểm:
*Hiệu năng, đó là phiên bản "built" của Dojo, có nghĩa là với mỗi module được giảm thiểu và tối ưu hóa để truyền tải hiệu quả trên Internet. Nó có nghĩa là khi bạn có vấn đề, thật khó để bắt lỗi.
*Họ yêu cầu người dùng của bạn phải truy cập Internet công khai để dùng ứng dụng của bạn. Trong rất nhiều trường hợp có thể có hoặc có thể không thực tế.
*Cần phải tốn công hơn để tùy chỉnh các modules của riêng bạn.
*Nếu bạn muốn sản phẩm hóa ứng dụng của mình, một phiên bản tích hợp của Dojo phù hợp với mục tiêu ứng dụng và trình duyệt cụ thể sẽ tăng hiệu suất ứng dụng hơn, điều mà bạn không thể đạt được với một bản build CDN theo kiểu "one-size fits all" (tạm dịch: một cỡ cho tất cả - nghe như quần áo may sẵn ấy!).

Để bắt đầu phát triển ứng dụng Dojo, thực hiện các bước sau để sử dụng tài nguyên của Dojo

1. Tải xuống Dojo (ở phía gần cuối có các gói mà bạn cần tải xuống)
Nếu bạn đã có kinh nghiệm với git hoặc GitHub , bạn có thể tạo các bản sao từ GibHub . Tối thiểu, hãy tải dojo . Bạn cũng sẽ cần dijit , dojox , và util
2. Xả file nén Dojo vào trong thư mục dự án của bạn, ví dụ:
hellodojo.html
demo/
myModule.js
dojo/
dijit/
dojox/
util/
3. Tải <dojo.js> cục bộ, tốt hơn là từ CDN:
<script src="dojo/dojo.js"></script>
4. Cập nhật cấu hình gói của bạn
var dojoConfig = {
async : true,
baseUrl: '.',
packages: [
'dojo',
'dijit',
'dojox',
'demo'
]
}

Getting Help – Tìm kiếm giải pháp khi gặp lỗi

Mỗi khi bạn gặp nhầm lẫn hoặc khó khăn thì bạn không phải là người duy nhất đâu! Các tình nguyện viên luôn sẵn sàng hỗ trợ qua email trong dojo-interesting mailing list hay qua IRC . Nếu bạn nghĩ bạn đã tìm thấy lỗi trong tài liệu của chúng tôi hay hiểu lầm, khó hiểu, hãy phản hồi ở cuối mỗi tài liệu để cho chúng tôi biết.
Nếu bạn cần trợ giúp gấp hoặc bí mật, hoặc có một vấn đề không thể giải quyết được với các tình nguyện viên của chúng tôi, hỗ trợ thương mại commercial Dojo support  và hội thảo đào tạo training workshops luôn sẵn có

Where to next ? – Tiếp theo ta sẽ học gì  ?

Bắt đầu với bộ công cụ Dojo thật đơn giản để thêm một thẻ <script> và yêu cầu (<require>) vài modules, nhưng phạm vi lớn và khả năng của Dojo đồng nghĩa với việc chúng ta mới chỉ lướt sơ qua về Dojo. Tùy thuộc vào nhu cầu của bạn, có vài hướng đi để bạn chọn lựa:
*Nếu bạn đã sử dụng Dojo trước đây và muốn hiểu nhiều hơn về thế giới AMD và "baseless" Dojo, hiểu thêm về những khái niệm đã thay đổi, bạn nên xem qua bài viết Modern Dojo
*Nếu bạn thích khi thêm một vài thuộc tính và hiệu ứng cho web hiện tại hoặc máy chủ điều kiện, bạn sẽ muốn xem phần tiếp theo Using dojo/query , Event with dojo  và effect hay aninmations
*Nếu bạn muốn thêm Ajax cho trang web của mình, Ajax with dojo là điều bạn đang tìm kiếm.
*Nếu bạn đang tìm cách để tích hợp thư viện widget vào website hoặc ứng của bạn, hãy xem Creating Template-based Widgets và tutorial series on Dijit widgets
*Nếu bạn đang cố gắng học nhiều hơn về kiến trúc ứng dụng web phức tạp và phát triển các khả năng hữu ích của Dojo, hãy xem qua phần Core Concept
*Nếu mục đích của bạn là ứng dụng mobile, mời bạn xem Getting Started with dojoX/mobile .

Cho dù kết quả bạn mong muốn thế nào, Dojo cung cấp bộ công cụ mã nguồn mở hàng đầu, nhờ vậy có thể giúp bạn hoàn thành dự án của mình nhanh hơn cùng những kết quả bất ngờ. Chúng tôi đang chờ đợi bạn phát triển cùng chúng tôi.

Giới thiệu về AMD

link gốc : http://dojotoolkit.org/documentation/tutorials/1.10/modules/

Introduction to AMD Modules - Giới thiệu về module AMD (Asynchronous Module Definition)

Dojo hỗ trợ việc viết các modules bằng cú pháp khai báo bất đồng bộ Module (Asynchronous Module Definition), điều này giúp mã nguồn dễ viết và dễ bắt lỗi hơn. Trong bài hướng dẫn này, chúng tôi sẽ trình bày những kiến thức cơ bản và cách dùng AMD.
Nếu đã học Dojo và bắt đầu chuyển sang phiên bản 1.7, bạn cần tìm bản 1.8 và các hướng dẫn để chuyển từ module cũ sang AMD. Bài viết này chỉ tập trung kỹ về AMD.

Overview - Tổng quan

Cú pháp AMD là một cú pháp Dojo đề nghị khi bắt đầu học Dojo 1.7 . Nó cung cấp rất nhiều cải tiến từ Module Dojo ban đầu, bao gồm đầy đủ hệ thống bất đồng bộ, các gói di động, quản lý tốt hơn, và cải thiện việc hỗ trợ gỡ lỗi. Nó cũng là một định hướng cộng đồng tiêu chuẩn, nghĩa là các module ghi vào đặc tính kỹ thuật AMD có thể được sử dụng với bất kỳ loader (từ đoạn này trở đi chúng tôi xin phép gọi loader là trình tải) hoặc thư viện AMD tương thích. Trong bài này, chúng tôi sẽ giải thích về AMD và trình bày với bạn cách để dùng nó.

What is a module? - Module là gì ?

Một module là một giá trị có thể truy cập bởi một tham chiếu duy nhất. Nếu bạn có nhiều phần dữ liệu hoặc hàm mà bạn muốn sử dụng trong module, chúng phải có các thuộc tính trong một đối tượng duy nhất-đại diện cho module (dịch chỗ này hơi khó hiểu, tóm lại, mỗi module thì phải có tên duy nhất, mỗi thuộc tính và hàm trong nó cũng duy nhất, cái này chắc ai cũng biết). Thực tế mà nói, thật cần thiết để tạo một module với giá trị đơn giản <var tinnyModule = 'simple Value'>, nhưng nó đã là một module rồi đấy. Module bắt đầu có ý nghĩa nhiều hơn trong quá trình module hóa của bạn-tách ra thành những tập con để xử lý một chức năng lớn. Nếu bạn muốn đại diện cho một người với các thông tin như tên, địa chỉ, và cả các phương thức nữa. Tất cả các thông tin đó đều được đặt tại một vị trí mã duy nhất. Một module được lưu trữ trong hệ thống của bạn như một tập tin duy nhất

How do I create a module? - Làm sao để tạo một module ?

Cùng với AMD, bạn tạo một module bởi việc đăng ký nó với một trình tải.
Nói ngắn gọn trình tải là một đoạn code Javascript (đúng vậy, nó chỉ là Javascript) xử lý việc khai báo và tải các module. Khi bạn tải <dojo.js> hoặc <require.js>, bạn đã gọi một trình tải AMD. Trình tải khai báo các hàm để tương tác với nó (define, require,...)
Hàm toàn cục <define> cho phép bạn đăng ký một module cùng với trình tải. Đây là vài ví dụ:
define(5);
Không quá phức tạp nhưng bạn đã đăng ký một module rồi đấy, và giá trị của nó là 5
define ({
thuVien: 'dojo'
phienBan: 1.10
})
Khi module này được tải, chúng ta có 2 thuộc tính
define(function(){
var giaTriCucBo = 0;
return {
tang: function() {
giaTriCucBo++;
}

giam: function() {
giaTriCucBo--;
}

layGiaTri: function(){
return giaTriCucBo;
}
};
});
Trong trường hợp này, chúng ta đã tạo một hàm nhờ <define>. Hàm này được đánh giá và giá trị của nó được lưu lại bởi trình tải như là một module. Đoạn mã được đóng trong {} để tạo nên giá trị cục bộ (không thể được truy cập từ bên ngoài). Tuy nhiên ta vẫn có thể khảo sát và tính toán các biến này nhờ vào các phương thức được cung cấp trên đối tượng được trả về giống như là giá trị của module.

How do I load a module? - Làm thế nào để tải một Module ?

Đối với người mới bắt đầu, chúng ta cần hiểu cách module được định nghĩa. Để tải module, bạn cần một vài cách định nghĩa chúng. Tương tự như hệ thống module/package của các ngôn ngữ lập trình khác, một AMD module được xác định bởi đường dẫn và tên file của chúng. Hãy lưu đoạn mã ở ví dụ trên vào trong một thư mục
app/dem.js (dem.js chứa nội dung là ví dụ lúc nãy)
Đồng thời thêm một trình tải (tất nhiên là của Dojo) và một tệp index.html - điểm bắt đầu ứng dụng của bạn. Điều này cho chúng ta biết cấu trúc của một file
/
    index.html
    /dojo/
    /app/
        dem.js

Trang index sẽ trông giống như thế này
<html>

    <body>

        <script src=&quot;dojo/dojo.js&quot; data-dojo-config="async: true"></script>

        <script>

            require([

                &quot;app/dem&quot;

            ], function(dem){

                log(dem.layGiaTri());

                dem.tang();

                log(dem.layGiaTri());

                dem.giam();

                log(dem.layGiaTri());

            });

        </script>

    </body>

</html>

(chi chú: &quot; = " )
Xem lại điều gì đang xảy ra ở đây:
1. Trong <app/dem.js>, chúng ta gọi <define> để đăng ký một module cùng với trình tải. Chú ý là module của chúng ta tạo ra chỉ tham chiếu tới một đối tượng, không phải là một cấu trúc hàm - nghĩa là với tất cả bit của mã nạp module này sẽ nhận được một tham chiếu chính xác đến đối tượng như thế. Nói chung các module đều trả về các cấu trúc, nhưng trong vài trường hợp, nó được dành riêng cho việc chỉ để trả về một đối tượng đơn lẻ.
2.Bằng cách định vị module của chúng ta trong hệ thống tập tin, trong thư mục con, bên dưới thư mục chứa <index.html> và trong thư mục "anh em" (cùng cấp) của trình tải AMD (<dojo/dojo.js>), chúng ta không phải cấu hình thêm để trình tải biết rằng định danh module <app/dem> tải tệp <app/dem.js> và dùng nó để trả giá trị của module.
3.Trong tệp index.html, chúng ta gọi <require> để tải module <app/dem>. Bạn có thể tải module đơn giản bằng <require(["app/dem"])>. Nếu mã trong module có tác dụng khác(như tác động tới các module khác), bạn có thể không cần tham chiếu tới module ở mọi nơi. Tuy nhiên, nếu cần tham chiếu tới module, bạn cần một hàm callback. Trình tải sẽ chắc chắn rằng module của bạn đã được tải và một khi nó có module đó, nó sẽ gọi hàm callback để truyền từng module vào như là một tham số của hàm. Như bất cứ các hàm khác, bạn tự do trong việc đặt tên cho bất cứ tham số nào bạn muốn (không yêu cầu tên tham số liên quan đến tên module). Điều đó cũng có nghĩa là cần phải thực hành tốt để sử dụng tên giống với tên module.

Modules Loading Modules - Module tải Module

Các ví dụ trên đã cho thấy thật đơn giản để sữ dụng hàm <define>. Khi một ứng dụng đã được tổ chức tốt, nghĩa là các giữa các module có mối quan hệ rất tự nhiên. Hàm <define> có thể tự động tải các phần phụ thuộc vào hàm của bạn. Danh sách phụ thuộc được thông qua nhờ <define> trước giá trị module.
define([

    "dojo/_base/declare",

    "dojo/dom",

    "app/dateFormatter"

], function(declare, dom, dateFormatter){

    return declare(null, {

        showDate: function(id, date){

            dom.byId(id).innerHTML = dateFormatter.format(date);

        }

    });

});

Ví dụ này chứng minh một vài thuộc tính điển hình của ứng dụng AMD:
1. Nhiều sự phụ thuộc - cả hai module "dojo/dom" và "app/dateFormatter"(giả sử là có module này với chức năng định dạng hiển thị ngày tháng) được xác định trong danh sách phụ thuộc.

2. Trả về một cấu trúc - một cái tên riêng biệt cho module như thế này sẽ là một cái gì đó giống như "app/DateManager"(ta hiểu rằng module này sẽ có chức năng xử lý ngày tháng và sẽ lưu vào tệp tin app/DateManager.js). Đoạn mã dưới đây sẽ giúp bạn hiểu rõ hơn:
require([
    "app/DateManager"
], function(DateManager){
    var dm = new DateManager();
    dm.showDate('dateElementId', new Date());
});
Trong khi AMD là một trong những chủ đề đầu tiên bạn nên làm quen trước khi phát triển Dojo, thì <declare> (khai báo) là một hàm quan trọng khác - Nếu bạn chưa sẵn sàng quen với dojo/_base/declare , hãy đọc hướng dẫn này http://dojotoolkit.org/documentation/tutorials/1.10/declare/

Using pulgins - Dùng các plugin

Ngoài module bình thường, trình tải AMD cũng có một loại module mới gọi là plugin. Các plugin được dùng để mở rộng trình tải với các thuộc tính mới ngoài việc đơn giản là tải các module AMD. Các plugin được tải nhiều hay ít giống như các module bình thường nhưng dùng thêm một ký tự đặc biệt là dấu chấm than "!" ở cuối tên plugin. Dữ liệu sau dấu chấm than "!" được trực tiếp thông qua plugin để xử lý. Sẽ dễ hiểu hơn khi nhìn vào một số ví dụ. Dojo có một vài plugin mặc định, 4 plugin quan trọng nhất trong đó là: <dojo/text>, <dojo/i18n>, <dojo/has> và <dojo/domReady>. Hãy xem cách sử dụng chúng như thế nào:

dojo/text

<dojo/text> được dùng khi bạn cần tải một chuỗi từ file (như một mẫu HTML). Giá trị sẽ được lưu trữ (trong bộ đệm), để nếu có gọi lại các tệp đã lưu trữ thì không cần phải lấy lại từ máy chủ nữa. The builder(trình xây dựng) sẽ ghép các chuỗi được tải lên thành một hàng bằng <dojo/text>. Vì vậy, trong một số ví dụ, để tải một mẫu widget(tiện ích con, control con...), bạn sẽ phải khai báo module của mình như sau:
//trong "my/widget/NavBar.js"
define([
"dojo/_base/declare",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dojo/text!./templates/NavBar.html"
],function(declare,_WidgetBase,_TemplatedMixin,template){
return declare([_WidgetBase,_TemplatedMixin],{
//template chứa nội dung trong file "my/Widget/templates/NavBar.html"
templateString: template
});
});

dojo/i18n

<dojo/i18n> tải bộ tài nguyên ngôn ngữ tùy theo sự địa phương hóa trong mỗi trình duyệt web của bạn. Sử dụng như thế này:
// trong "my/widget/Dialog.js"
define([
"dojo/_base/declare",
"dijit/Dialog",
"dojo/i18n!./nls/common"
],function(declare,Dialog,i18n){
return declare(Dialog,{
title: i18n.dialogTitle
})
});
Để hiểu thêm về <i18n>, mời bạn đọc bài internationalization tutorial ( http://dojotoolkit.org/documentation/tutorials/1.10/i18n/ )

dojo/has

Trình tải Dojo bao gồm một bản thực thi của <has.js> để phát hiện API; plugin <dojo/has> sẽ tăng khả năng yêu cầu module cho trình nạp một cách có điều kiện. Nó được dùng như sau:
// in "my/events.js"
define([
    "dojo/dom",
    "dojo/has!dom-addeventlistener?./events/w3c:./events/ie"
], function(dom, events){
    // tham số events của hàm callback sẽ nạp từ module "my/events/w3c" nếu kiểm tra thấy có sử dụng API "dom-addeventlistener", nếu không thì sẽ là "my/events/ie"
    events.addEvent(dom.byId("foo"), "click", function(){
        console.log("Foo clicked!");
    });
});

dojo/domReady

<dojo/domReady> được thay thế cho <dojo.ready>. Đơn giản, một module sẽ không được xử lý cho tới khi DOM đã sẵn sàng. Sử dụng:
// trong "my/app.js"
define(["dojo/dom", "dojo/domReady!"], function(dom){
    // hàm này sẽ không được thực thi cho đến khi DOM đã sẵn sàng
    dom.byId("someElement");
});
Chú ý rằng chúng ta không thể khai một báo tham số trong hàm callback của mình để trả về bất kỳ giá trị nào của dojo/domReady. Đó là bởi vì nó trả về giá trị không phải là giá trị - chúng ta đơn giản chỉ dùng nó để hoãn lại việc gọi lại hàm callback. Yêu cầu các modules hoặc plugins với các giá trị không sử dụng có thể đặt ở phần cuối danh sách yêu cầu phụ thuộc, để sắp xếp các module và các biến cục bộ phụ thuộc một cách trật tự hơn.

Ngay cả khi không có dữ liệu nạp vào, thì dấu chấm than vẫn cần phải có. Nếu không có nó, bạn sẽ chỉ nạp module <dojo/domReady> như một module phụ thuộc thay vì kích hoạt tính năng đặc biệt của plugin.

Conclusion - Kết luận
Kiến thức căn bản về AMD cung cấp trong bài viết hướng dẫn này sẽ giúp bạn có những bước đầu trong hành trình phát triển với Dojo. Nhưng bạn sẽ sớm gặp những vấn đề phức tạp hơn. Hãy đọc bài Advanced AMD Usage ( http://dojotoolkit.org/documentation/tutorials/1.10/modules_advanced/ ) để giải quyết chúng:
* Cấu hình trình nạp để nó làm việc khi nạp và các packages ở những vị trí khác nhau, thậm chí ở những server khác nhau.
* Tạo các packages module di động (portble/tức là có thể xách đặt ở đâu cũng được--chứ không phải là riêng các gói cho mobile).
* Nạp nhiều phiên bản của module hoặc thư viện.
* Nạp mã non-AMD

Source - Nguồn

AMD Specification ( https://github.com/amdjs/amdjs-api/wiki/AMD )

Thứ Tư, 22 tháng 4, 2015

DojoToolkit - Hướng dẫn tham khảo

BỘ CÔNG CỤ DOJO - HƯỚNG DẪN THAM KHẢO

Link gốc bài viết: http://dojotoolkit.org/reference-guide/1.10/index.html

CHÀO MỪNG

Phần hướng dẫn được thiết kế với chiều sâu mã nguồn liên quan đến bộ công cụ Dojo. Tài liệu là nỗ lực chung và đã được đóng góp bởi những người đã đồng ý với các thỏa thuận tại đây với nền tảng Dojo.

Nếu bạn đang tìm kiếm hướng dẫn dùng bộ công cụ Dojo, bạn nên tham khảo tài liệu này http://dojotoolkit.org/documentation/
Hoặc nếu bạn đang tìm kiếm những thông tin chi tiết về các thuộc tính, phương thức hay sự kiện của một module nào đó, tốt hơn bạn nên tham khảo tài liệu này http://dojotoolkit.org/api/

BỘ CÔNG CỤ DOJO

Bộ công cụ Dojo được chia thành những gói chính như sau:
- Dojo: Đôi khi được gọi là phần lõi, đây là phần chính của Dojo và nói chung các gói ứng dụng và module đều được chứa trong nó. Phần lõi có các chức năng như AJAX, thao tác DOM, lập trình các lớp, sự kiện, ủy thác, lưu trữ dữ liệu, kéo thả và quốc tế hóa các thư viện.
- Dijit: Là một phần mở rộng của việc thiết lập các Widget (chức năng-các thành phần giao diện người dùng) và hệ thống cơ bản hỗ trợ chúng. Nó được xây dựng đầy đủ trên đỉnh của phần lõi Dojo.
- DojoX: Là bộ sưu tập của các gói và module, nó cung cấp các mảng chức năng nhất định được xây dựng trên cả lõi Dojo và Dijit. Các gói và module đều được chứa trong DojoX sẽ có sự khác nhau về mức độ hoàn thành, ký hiệu trong các file README ở mỗi gói. Một vài module đã hoàn tất và một vài còn đang ở mức thực nghiệm cao.
- Util: những công cụ khác nhau hỗ trợ phần còn lại của bộ công cụ, như khả năng xây dựng, kiểm tra và tài liệu mã nguồn.

Một trong những mục tiêu dài hơi của bộ công cụ Dojo là tiếp tục tạo các gói với nhiều tương tác hơn và sẽ không cần phải (gọi lệnh require để) yêu cầu thêm các gói thư viện trong có trong DojoX. Một vài gói hiện tại đã công bố là : 
- dgrid: một lưới hiển thị dữ liệu với đầy đủ chức năng, gọn nhẹ.
- gridx: phản hồi giao diện nhanh hơn, module hóa, bổ sung cho lưới dữ liệu cơ bản.

Hướng dẫn tham khảo cấu trúc
Phần này không chỉ chứa các gói công cụ chính, nó cũng cung cấp một phần các thông tin liên quan:
- Release Notes - Các ghi chú phát hành của Dojo Toolkit và vài ghi chú phát hành khác liên quan đến quá trình chuyển đổi các ghi chú.
- Developer Notes - Các tài liệu hướng dẫn cho những thành viên đóng góp và tham gia phát triển Dojo.

Tổng quan Dojo

DOJO: TỔNG QUAN

(Tôi xin gọi DojoToolkit là Dojo)

Liên kết: http://dojofoundation.orghttp://dojotoolkit.org
Công cụ hỗ trợ dịch: google translate
Công cụ hỗ trợ cho các ví dụ: https://jsfiddle.net
- Dojo theo như slogan của chính trang chủ sản phẩm "A JavaScript toolkit that saves you time and scales with your development process." - Tạm dịch "Một bộ công cụ JavaScript giúp bạn tiết kiệm thời gian và quy mô cùng với quá trình phát triển của bạn." (Theo google translate)
- Dojo theo như phát biểu của hãng Esri thì "Dojo is an open source toolkit that helps you write robust and efficient JavaScript code." - tạm dịch "Dojo là một bộ công cụ mã nguồn mở giúp bạn viết mã JavaScript mạnh mẽ và hiệu quả."
Thật vậy, nó là một trong những framework JS rất tốt khi phát triển các app business (tuy nhiên, tại thời điểm tôi viết bài này thì bạn lên google gõ "best js framework 2015" thì sẽ ko thấy dojo nằm đâu hết. Có cái nàyhttp://www.developerslane.com/archives/1459 đánh giá 21 framework js tốt nhất thì dojo cũng ko xuất hiện).
Vậy tại sao tôi lại chọn Dojo khi phát triển các app của mình? Có 2 lý do:
- Khách quan: tôi đang phát triển các ứng dụng web được dây xựng trên nền tảng của Dojo. Cụ thể là các ứng dụng bên cạnh sản phẩm của hãng Esri.
- Chủ quan: 
 + tôi đã tìm hiểu vài framework js hiện tại như jQuery (cái này thì quá chuẩn rồi), AngularJS (cục cưng của google, phát triển năm 2009 đến nay), KnockoutJS... (chơi chung với các ứng dụng của Microsoft, cụ thể làASP.NET, phát triển từ 2010 đến nay, ai dùng Tower framework chắc rành), BackbornJS, ExtJS (của đồng chí Sencha, tốn tiền mới sài được, tốt nhưng mà e né, tiền đâu mà chơi)... nhưng tôi thích Dojo nhất. Và khi sử dụng Dojo, tôi phát triển giao diện dựa trên mã lập trình js chứ ít khi sử dụng khai báo HTML; nếu các bạn thích mô hình DOM, muốn theo tiêu chí "Let dynamic is dynamic" thì chắc các bạn cũng theo style như tôi Biểu tượng cảm xúc smile . Và Dojo là một framework tương tác DOM rất tốt. 
 + Ngoài ra, tôi đã từng làm các ứng dụng Winform nên thường xuyên sử dụng framework DevExpress Winform. Cái này thư viện nó rất tốt, hỗ trợ các control cho ứng dụng quản lý là tuyệt vời.... và ở đây, Dojo có mảng Dijit+Dojox cũng có rất nhiều control hỗ trợ cho ứng dụng quản lý.... và đặc biệt là free Biểu tượng cảm xúc pacman Biểu tượng cảm xúc smile .
(Nói về chủ quan thì còn nhiều nữa... tạm thời như thế, sau này bổ sung tiếp nếu có cơ hội)

Ngay thời điểm tôi viết bài này là version 1.10, chính xác là 1.10.4, Dojo đã giới thiệu bản 2.0.... nghe nói đã lắm và các thành phần của DojoX sẽ cho thẳng vào Dojo hoặc Dijit. Còn về xử lý lưới hiển thị dữ liệu thì sẽ chuyển dần từ DataGrid, GridX... sang Dgrid http://dgrid.io
Ngoài ra, tôi cùng các thành viên cùng là việc cũng đang chuyển dần Server-Side từ ASP.NET WEB API 2 sang NodeJS cho nó hợp thời trang... Biểu tượng cảm xúc pacman Biểu tượng cảm xúc smile Nên việc dịch một tài liệu như Dojo ra cũng là một trong những điều hỗ trợ chúng tôi rèn luyện tốt hơn.
Đây là bài viết đầu tiên về Dojo trong chuỗi bài dịch về framework này nên chắc chắc không tránh khỏi sai sót như: quăng bom, chém gió, lấy của người khác thành ý kiến của mình, ăn cắp ý tưởng... vô tội vạ vân vân....
Nội dung cũng chưa mang đến cho bạn những bài viết cụ thể vào một thành phần nào của Dojo. Mong mọi người góp ý chân thành để nhóm chúng tôi phát triển thêm nhiều bài khác.
Chúc mọi người một ngày mạnh khỏe và hạnh phúc!