AngularJS Module類的方法

AngularJS中的Module類負責定義應用如何啟動砾赔,它還可以通過聲明的方式定義應用中的各個片段。我們來看看它是如何實現(xiàn)這些功能的。


一.Main方法在哪里
? ?如果你是從Java或者Python編程語言轉過來的师脂,那么你可能很想知道AngularJS里面的main方法在哪里物舒?這個把所有東西啟動起來,并且第一個被執(zhí)行的方法在哪里昭抒?JavaScript代碼里面負責實例化并且把所有東西組合到一起评也,然后命令應用開始運行的那個方法在哪里?

事實上灭返,AngularJS并沒有main方法盗迟,AngularJS使用模塊的概念來代替main方法。模塊允許我們通過聲明的方式來描述應用中的依賴關系熙含,以及如何進行組裝和啟動罚缕。使用這種方式的原因如下:

  1. 模塊是聲明式的。這就意味著它編寫起來更加容易怎静,同時理解起來也很容易邮弹,閱讀它就像讀普通的英文一樣!
  2. 它是模塊化的蚓聘。這就迫使你去思考如何定義你的組件和依賴關系腌乡,讓它們變得更加清晰。
  3. 它讓測試更加容易夜牡。在單元測試呂与纽,你可以有選擇地加入模塊,并且可以避免代碼中存在無法進行單元測試的內容塘装。同時急迂,在場景測試中,你可以加載其他額外的模塊蹦肴,這樣就可以更好地和其他組件配合使用僚碎。

例如,在我們的應用中有一個叫做"MyAwesomeApp"的模塊阴幌。在HTML里面勺阐,只要把以下內容添加到<html>標簽中(或者從技術上說卷中,可以添加到任何標簽中):

<html ng-app="MyAwesomeApp">

ng-app指令就會告訴AngularJS使用MyAwesomeApp模塊來啟動你的應用。那么皆看,應該如何定義模塊呢仓坞?舉例來說,我們建議你為服務腰吟、指令和過濾器分別定義不同的模塊无埃。然后你的主模塊可以聲明依賴這些模塊。

這樣可以使得模塊管理更加容易毛雇,因為它們都是良好的嫉称、完備的代碼塊,每個模塊有且只有一種職能灵疮。同時织阅,單元測試可以只加載它們所關注的模塊,這樣就可以減少初始化的次數(shù)震捣,單元測試也會變得更精致荔棉、更專注。


二.加載和依賴
? ?模塊加載動作發(fā)生在兩個不同的階段蒿赢,這一點從函數(shù)名上面就可以反映出來润樱,它們分別是Config代碼塊和Run代碼塊(或者叫做階段)。
1. Config代碼塊
? ?在這一階段里面羡棵,AngularJS會連接并注冊好所有數(shù)據源壹若。因此,只有數(shù)據源和常量可以注入到Config代碼塊中皂冰。那些不確定是否已經初始化好的服務不能注入進來店展。

  1. Run代碼塊
    ? ?Run代碼塊用來啟動你的應用,并且在注射器創(chuàng)建完成之后開始執(zhí)行秃流。為了避免在這一點開始之后再對系統(tǒng)進行配置操作赂蕴,只有實例和常量可以被注入到Run代碼塊中。你會發(fā)現(xiàn)舶胀,在AngularJS中睡腿,Run代碼塊是與main方法最類似的東西。

三.快捷方法
? ?利用模塊可以做什么呢峻贮?我們可以用它來實例化控制器[1]、指令[2]应闯、過濾器[3]以及服務[4]纤控,但是利用模塊類還可以做更多事情。如下模塊配置的API方法:

  1. config(configFn) 配置
    ? ?利用此方法可以做一些注冊工作碉纺,這些工作需要在模塊加載時完成船万。

     angular.module('myModule', [])
       . config(function(injectables) {                   // 配置(功能(注射劑)
         // provider-injector                             // 提供者噴射器
         // This is an example of config block.           // 這是一個示例的配置塊刻撒。
         // You can have as many of these as you want.    // 你可以盡可能多的你想要的。
         // You can only inject Providers (not instances) // 只能注入提供者(而不是實例)
         // into config blocks.                           // 配置塊耿导。
       })
    
  2. constant(name, object) 常數(shù)恒量
    ? ?此方法會首先運行声怔,所以你可以用它來聲明整個應用范圍內的常量,并且讓它們在所有配置(config方法)和實例(后面的所有方法舱呻,例如controller醋火、service等)方法中可用。
    ?? constant(常量)用來在配置階段傳遞數(shù)值箱吕,注意這個常量在配置階段是不可用的芥驳。

     mainApp.constant("configParam", "constant value");
    
  3. controller(name,constructor) 控制器
    ? ?它的基本作用是配置好控制器方便后面使用。

  4. directive(name,directiveFactory) 指令
    ? ?可以使用此方法在應用中創(chuàng)建指令茬高。

  5. filter(name,filterFactory) 過濾器
    ? ?允許你創(chuàng)建命名的AngularJS過濾器兆旬,就像前面章節(jié)所討論的那樣。

  6. run(initializationFn) 運行
    ? ?如果你想要在注射器啟動之后執(zhí)行某些操作怎栽,而這些操作需要在頁面對用戶可用之前執(zhí)行丽猬,就可以使用此方法。

     run(function(injectables) {                         // 運行(函數(shù)(注射劑)
       // instance-injector                              // 實例噴射器
       // This is an example of a run block.             // 這是一塊運行的一個例子熏瞄。
       // You can have as many of these as you want.     // 你可以盡可能多的你想要的脚祟。
       // You can only inject instances (not Providers)  // 只能注入實例(而不是提供者)
       // into run blocks                                // 運行塊
     });
    
  7. value(name,object)
    ? ?允許在整個應用中注射值。
    ?? Value 是一個簡單的 javascript 對象巴刻,用于向控制器傳遞值(配置階段):

     // 定義一個模塊
     var mainApp = angular.module("mainApp", []);
     // 創(chuàng)建 value 對象 "defaultInput" 并傳遞數(shù)據
     mainApp.value("defaultInput", 5);
    
     // 將 "defaultInput" 注入到控制器
     mainApp.controller('CalcController', function($scope, CalcService, defaultInput) { 
       $scope.number = defaultInput; 
       $scope.result = CalcService.square($scope.number); 
       $scope.square = function() { 
         $scope.result = CalcService.square($scope.number); 
       }
     });
    
  8. factory(name,factoryFn)
    ? ? 如果你有一個類或者對象愚铡,需要首先為它提供一些邏輯或者參數(shù),然后才能對它初始化胡陪,那么你就可以使用這里的factory接口沥寥。factory是一個函數(shù),它負責創(chuàng)建一些特定的值(或者對象)柠座。我們來看一個greeter(打招呼)函數(shù)的實例邑雅,這個函數(shù)需要一條問候語來初始化:

     function Greeter(salutation) { 
       this.greet = function(name) { 
         return salutation + ' ' + name;
       };
     }
    

greeter函數(shù)示例如下:

    myApp.factory('greeter', function(salut) { 
      return new Greeter(salut);
    });

然后可以這樣來調用它:

    var myGreeter = greeter('Halo');

factory 是一個函數(shù)用于返回值。在 service 和 controller 需要時創(chuàng)建妈经。
通常我們使用 factory 函數(shù)來計算或返回值淮野。

  1. service(name,object)
    ? ?factory和service之間的不同點在于,factory會直接調用傳遞給它的函數(shù)吹泡,然后返回執(zhí)行的結果骤星;而service將會使用"new"關鍵字來調用傳遞給它的構造方法,然后再返回結果爆哑。所以洞难,前面的greeter Factory可以替換成下面這個greeter Service:

     myApp.service('greeter', Greeter);
    

每當我們需要一個greeter實例的時候,AngularJS就會調用新的Greeter()來返回一個實例揭朝。

  1. provider(name,providerFn)
    ? ?provider是這幾個方法中最復雜的部分(顯然队贱,也是可配置性最好的部分)色冀。provider中既綁定了factory也綁定了service,并且在注入系統(tǒng)準備完畢之前柱嫌,還可以享受到配置provider函數(shù)的好處(也就是config塊)锋恬。
    ??AngularJS 中通過 provider 創(chuàng)建一個 service、factory等(配置階段)编丘。
    Provider 中提供了一個 factory 方法 get()与学,它用于返回 value/service/factory。
    ? ?我們來看看使用provider改造之后的greeter Service是什么樣子:

    myApp.provider('greeter', function() { 
      var salutation = 'Hello'; 
      this.setSalutation = function(s) { 
        salutation = s;
      } 
      function Greeter(a) { this.greet = function() { 
        return salutation + ' ' + a;
      }} 
      this.$get = function(a) { 
        return new Greeter(a);
      };
    });
    

這樣我們就可以在運行時動態(tài)設置問候語了(例如瘪吏,可以根據用戶使用的不同語言進行設置)癣防。

    var myApp = angular.module(myApp, [])
      .config(function(greeterProvider) {
        greeterProvider.setSalutation('Namaste')    \
      ;}
     );

每當有人需要一個greeter實例時,AngularJS就會在內部調用$get方法掌眠。

附: angular.module('MyApp',[...])和angular.module('MyApp')之間有一個很小但是卻很重要的不同點

angular.module('MyApp',[...])會創(chuàng)建一個新的Angular模塊蕾盯,然后把方括號([...])中的依賴列表加載進來;而angular.module('MyApp')會使用由第一個調用定義的現(xiàn)有的模塊蓝丙。
? ?所以级遭,對于以下代碼,你需要保證在整個應用中只會使用一次:

angular.module('MyApp', [...]) //如果你的應用是模塊化的渺尘,這里可能是MyModule

如果你不打算把模塊的引用存到一個變量中挫鸽,然后在整個應用中通過這個變量來引用模塊,那么鸥跟,在其他文件中使用angular.module(MyApp)的方式可以保證得到正確的AngularJS模塊引用丢郊。模塊上的所有東西都必須通過訪問這個模塊引用來定義,或者在模塊定義的地方把那些必備的內容添加上去医咨。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末枫匾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子拟淮,更是在濱河造成了極大的恐慌干茉,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件很泊,死亡現(xiàn)場離奇詭異角虫,居然都是意外死亡,警方通過查閱死者的電腦和手機委造,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門戳鹅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人昏兆,你說我怎么就攤上這事枫虏。” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵模软,是天一觀的道長。 經常有香客問我饮潦,道長燃异,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任继蜡,我火速辦了婚禮回俐,結果婚禮上,老公的妹妹穿的比我還像新娘稀并。我一直安慰自己仅颇,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布碘举。 她就那樣靜靜地躺著忘瓦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪引颈。 梳的紋絲不亂的頭發(fā)上耕皮,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音蝙场,去河邊找鬼凌停。 笑死,一個胖子當著我的面吹牛售滤,可吹牛的內容都是我干的罚拟。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼完箩,長吁一口氣:“原來是場噩夢啊……” “哼赐俗!你這毒婦竟也來了?” 一聲冷哼從身側響起嗜憔,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤秃励,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吉捶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夺鲜,經...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年呐舔,在試婚紗的時候發(fā)現(xiàn)自己被綠了币励。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡珊拼,死狀恐怖食呻,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤仅胞,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布每辟,位于F島的核電站,受9級特大地震影響干旧,放射性物質發(fā)生泄漏渠欺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一椎眯、第九天 我趴在偏房一處隱蔽的房頂上張望挠将。 院中可真熱鬧,春花似錦编整、人聲如沸舔稀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽内贮。三九已至,卻和暖如春赏半,著一層夾襖步出監(jiān)牢的瞬間贺归,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工断箫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拂酣,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓仲义,卻偏偏與公主長得像婶熬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子埃撵,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容