1、簡介
使用Dojo有兩種主要的方式,分別是編程式和聲明式。編程式使用JavaScript實例化對象,並且所有的代碼都編碼在JavaScript中;聲明式使用dojo/parser讀取DOM,並解析出被特殊屬性(后面我們會知道這個屬性是data-dojo-type)裝飾的節點和擴展控件行為的特定的<scrpt>標簽。
這兩種方式都有自己的優缺點,你可能同時使用這兩種方式。本文主要講解聲明式語法,使用聲明式語法,你需要考慮到下面幾點:
- 聲明式語法非常簡單,並且不需要更深的JavaScript只是。JavaScript可以實現的,聲明式語法幾乎都能實現,但是聲明式語法有它的限制。
- 由於聲明式語法的本質(類似html標簽),他的性能不如編程式好。因為需要使用dojo/parser解析DOM,並查找需要處理的節點。
2、實例化對象
聲明式語法最常用的方式是實例化組件。實現方式是:添加特殊的屬性(data-dojo-type)到html標簽中,並使用dojo/parser讀取文檔和實例化組件。看個例子:
- <button type="button" id="myButton" data-dojo-type="dijit/form/Button">
- <span>Click Me!</span>
- </button>
上面的例子中我們使用data-dojo-type指定了一個MID(模塊ID,這里是Dojo Button),它會指示dojo/parser在該節點在DOM中的位置處實例化一個dijit/form/Button對象。
可以注意到我們添加了一個id屬性,它在我們需要獲取這個組件的引用時有用。Dijit的基本組件在實例化時,會查找存放他們的節點,如果有id屬性,就會使用該id值在dijit/registry中注冊,以便將來可以通過該id來引用組件。
我們上面只是放置了一個標簽,接下來我們還需要激活dojo/parser。在引入AMD之前的版本,你可以使用Dojo配置data-dojo-config中的選項parseOnLoad:true來激活dojo/parser。這種使用方式在某些特殊情況下可能會導致非預想結果,因此建議在代碼中顯示的激活dojo/parser。
- <script type="text/javascript" src="lib/dojo/dojo.js"
- data-dojo-config="async: true"></script>
- <script type="text/javascript">
- require(["dojo/parser", "dojo/ready", "dijit/form/Button"],
- function(parser, ready){
- ready(function(){
- parser.parse();
- });
- });
- </script>
3、配置對象
使用dojo/parser實例化對象很強大,但是如果不能配置組件,就沒有任何意義。因此需要一個機制能夠在實例化時傳入配置信息。
在Dojo的早期版本,我們使用往標簽中添加屬性的方式,即使屬性不起作用。HTML5引進了一種該方式:允許自定義以data-開頭的屬性,並允許文檔嚴格驗證。因此我們使用專有的data-dojo-props屬性來包含實例化時需要傳送構造器的配置。 例如:
- <button id="btn1" data-dojo-type="dijit/form/Button"
- data-dojo-props="label:'click me',onClick:function(){console.log('yes,clicked');}">
- </button>
4、實例化非組件對象
dojo/parser一般用來實例化標簽(例如Dijit組件)中的可視化元素,它也可以用來實例化非可視對象。dojo/parser解析配置信息作為第一個參數,node節點的引用作為第二個參數。這對基於dojo/_base/declare的非可視元素也是可行的。
有一個問題是,常規的對象不像Dijit組件一樣有一個注冊(Dijit組件在實例化時會根據承載元素的id值在dijit/registry中注冊以便將來能獲取到組件的引用),因此為了在實例化之后能夠引用到這些對象,需要在全局區域創建一個引用。dojo/parse通過查找data-dojo-id屬性來完成這個工作。
- <div data-dojo-id="myStore" data-dojo-type="dojo/store/Memory"
- data-dojo-props="data: [
- { name: 'Alabama', id: 'AL' },
- { name: 'Alaska', id: 'AK' },
- { name: 'Arizona', id: 'AZ' },
- { name: 'California', id: 'CA' },
- { name: 'Colorado', id: 'CO' },
- { name: 'Connecticut', id: 'CT' },
- { name: 'New York', id: 'NY' }
- ]"></div>
- <select id="mySelect" name="state" value="CA"
- data-dojo-type="dijit/form/FilteringSelect"
- data-dojo-props="searchAttr: 'name', store: myStore"></select>
5、組件行為
處理組件的事件,我們最容易想到的是在JavaScript中編寫一段代碼來處理(例如調用組件的on方法)。實際上,也可以使用聲明式方式來處理事件。
為了在標簽中實現事件處理,我們需要使用”聲明式腳本“來完成。聲明是腳本可以讓dojo/parser獲取一段內聯代碼,並且在實例化對象時傳入進去。我們來看一個例子:
- <div id="someDialog" data-dojo-type="dijit/Dialog"
- data-dojo-props="title: 'Hello World!'">
- <p>I am a dialog. That makes me happy.</p>
- </div>
- <button type="button" id="myButton" data-dojo-type="dijit/form/Button">
- <span>Click Me!</span>
- <script type="dojo/on" data-dojo-event="click">
- var registry = require("dijit/registry");
- registry.byId("someDialog").show();
- </script>
- </button>
聲明式腳本支持的類型有dojo/on,dojo/aspect,dojo/watch,dojo/method,dojo/connect。
6、自動請求
dojo/parser在遇到一個類似MID的data-dojo-type值時,並且該模塊並沒有加載,dojo/parser在實例化這個對象之前會嘗試去請求這個模塊。這個特點非常好用,但是如果不小心的話它會影響你頁面的性能。
