從dojo.require的變遷看dojo設計的思想變化

dojo1.4的時候,我還在dojo.provide,dojo.delare來聲明一個新module。從dojo1.7開始,dojo開始使用Asynchronous Module Definition (AMD)來聲明一個新module.node

dojo1.7以前編程

dojo.provide("my._TemplatedWidget");
dojo.require("dijit._WidgetBase");
dojo.require("dijit._TemplatedMixin");
dojo.declare("my._TemplatedWidget", [ dijit._WidgetBase, dijit._TemplatedMixin ], {});

dojo1.7以後

define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin" ], function(declare, _WidgetBase, _TemplatedMixin){
    return declare([ _WidgetBase, _TemplatedMixin ], {});
});

第二種方法好像少了module的名字,而不是像之前那樣子declare("my._TemplatedWidget",[ _WidgetBase, _TemplatedMixin ], {})。其實,名字已經不重要了,在dojo1.7中,重要的是獲取module。爲何dojo1.7以後已經不重視module的名字了呢?後面我會講到。

在1.7以前,每次想動態的加載一些module,能夠用dojo.require,1.7以後,能夠用新的require方法。設計模式

dojo1.7以前安全

dojo.require("dojo.dom");
dojo.require("dojo.fx") 

dojo.addOnLoad(function(){
    // The piece we had before…
    var greeting = dojo.dom.byId("greeting");
    greeting.innerHTML += " from Dojo!";
 
    // …but now, with a fun animation!
    dojo.fx.slideTo({
        top: 100,
        left: 200,
        node: greeting
    }).play();
});

dojo1.7以後dom

require(["dojo/dom", "dojo/fx", "dojo/domReady!"], function(dom, fx){
    // The piece we had before…
    var greeting = dom.byId("greeting");
    greeting.innerHTML += " from Dojo!";
 
    // …but now, with a fun animation!
    fx.slideTo({
        top: 100,
        left: 200,
        node: greeting
    }).play();
});

從上面的例子能夠看出,dojo.require所須要的module都放入了define或require中的【】中了。這中新的設計模式被稱爲AMD。

dojo1.7之後幾乎不再須要相似以"."來鏈接的類名了。而是能夠將全部的代碼放入callback函數,而後使用require([dependencies], callback)的形式來執行。callback裏面再也沒有長名字了,均可以使用module的local名字。異步

從以上例子能夠看出,dojo自1.7之後,引入了Namespace和module相似的模式。類的名字已經再也不重要,重要的是module的文件地址。module以文件地址做爲namespace,主要爲了能經過http尋找到module的地址並引入。這樣就避免了1.7以前須要維護module名與文件結構所帶來的混亂。1.7以後,只維護module的文件地址。回到上面的問題,爲何declare([ _WidgetBase, _TemplatedMixin ], {})再也不給類賦名了呢?看下面例子:ide

require(["my/_TemplateWidget"], function(MyTemplate){
    var instance = new MyTemplate();
});

使用module地址來引入module,而後將裏面定義的class賦予MyTemplate本地變量,在callback函數中只須要使用本地變量名就能夠了。

Require的參數dependencies裏面包含兩類,一類是真正的依賴的類,另外一類是插件。好比["dojo/dom", "dojo/fx", "dojo/domReady!"],dojo/domReady就屬於插件,意思是當dom解析完畢之後再執行callback。對於依賴,若是不存在,dojo回去加載。當加載完成以後,將執行callback函數。函數

以上介紹了AMD中的MD部分,A還沒說。1.7以前的dojo.require使用的是同步XHR來獲取js的,拿到的js內容使用eval函數,使js文本編程真正的js,同步XHR會block全部的js執行,可見效率多麼的低。而1.7以後的require是使用重建<script>的方法來加載須要的js文件的,在script上註冊"load"事件的監聽。可見其是異步的,而且少了eval,效率提升了不少。綜合起來,就成了AMD。ui

不管dojo.require仍是require,都須要對散文件發送http請求。建議對經常使用的module進行壓縮,使用dojo的build system把用的全部module都壓縮到一個dojo.compressed.js文件中。一次請求得到多有的module。spa

AMD的風格帶來的好處

1,異步加載,安全和效率均提升

2,代碼乾淨,風格統一,不用再見到不少的dojo.xhrPost, dojo.io.iframe, dijit.Menu.

3,提供插件的功能,簡化一些事件的處理。

。。。應該還有,想不起來。

相關文章
相關標籤/搜索