本節書摘來自華章出版社《angularjs深度剖析與最佳實踐》一書中的第2章,第2.2節,作者 雪狼 破狼 彭洪偉,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視
與其他現代語言不同,目前版本的javascript(ecmascript 5)并沒有内置子產品化文法。但是,随着程式規模越來越大,子產品化的需求越來越重要,于是出現了require.js等第三方庫,試圖用庫來彌補語言的不足。angular并不依賴require.js等第三方庫,而是自己實作了子產品化系統,這個系統的核心就是子產品(module)。
我們先來回顧一下“子產品”的概念,然後自然就明白angular中的module是怎麼回事了。
所謂子產品是指把相關的一組程式設計元素(如類、函數、變量等)組織到同一個釋出包中。這些程式設計元素之間緊密協作,隐藏實作細節,隻通過公開的接口與其他子產品合作。
子產品是一個粒度适中的複用機關,也是最常見的複用形式。比如我們常用的第三方庫往往對外公開好幾個類,使用者隻要關注其公開接口就可以了,不用了解其實作細節,這種第三方庫就是一個“子產品”。
angular的module也是如此。angular中的程式設計元素包括service、directive、filter、controller等,它們隻有通過子產品進行“導出”才能供别人使用。如:angular.module('com.ngnice.app').service('ui', function() {...});語句的作用是:先取出一個名為com.ngnice.app的子產品,然後把function() {...}作為一個回調函數以ui作為名字注冊進去。這樣,别人就可以随時通過ui這個名字把它從com.ngnice.app子產品中取出來。
是以,我們可以簡單地把子產品看做一個系統資料庫(registry),它儲存着名字和程式設計元素的對照表,既可以存入,也可以取出。
一個程式往往不會隻含有一個子產品,這些子產品需要互相協作,這就導緻了子產品之間具有依賴關系,比如有一個可複用子產品,名叫common,而我們的應用想要使用其中名叫authhandler的service。那麼我們就要先聲明這種依賴關系:angular.module('com.ngnice.app', ['common']),這樣,angular就知道該去common子產品中查找這個名叫authhandler的service。如果沒有聲明這種依賴關系,那麼就算引入了它所在的javascript檔案,也照樣是無法找到的,這是新手很容易踩坑的地方,請特别注意。同時,angular還可以自動檢測出循環依賴,以免出現無限遞歸。
注意,我們剛才調用了兩次module函數:angular.module('com.ngnice.app')和angular.module('com.ngnice.app', ['common']),前者可不是後者的簡寫形式,而是具有完全不同的含義:前者的作用是引用一個子產品,也就是說查找一個名叫app的子產品,并傳回其引用,如果子產品不存在,則會觸發一個異常[$injector:nomod] module 'com.ngnice.app' is not available...;而後者的作用是建立一個子產品,并且聲明這個子產品需要依賴一個名為common的子產品,第二個參數是個數組,是以還可以聲明依賴更多個子產品。
子產品依賴關系是一棵樹,這就意味着:凡是依賴了app子產品的更進階子產品,也會自動依賴app所依賴的common等子產品。