AngularJs Modules詳解及範例程式碼_AngularJS

來源:互聯網
上載者:User

一、什麼是Module?

  很多應用都有一個用於初始化、載入(wires是這個意思嗎?)和啟動應用的main方法。angular應用不需要main方法,作為替代,module提供有指定目的的聲明式,描述應用如何啟動。這樣做有幾項優點:

  1. 這過程是聲明描述的,更加容易讀懂。
  2. 在單元測試中,不需要載入所有module,這對寫單元測試很有協助。
  3. 額外的module可以被載入到情景測試中,可以覆蓋一些設定,協助進行應用的端對端測試(end-to-end test)。
  4. 第三方代碼可以作為可複用的module打包到angular中。
  5. module可以通過任意順序或並行載入(取決於模組執行的延遲性,due to delayed nature of module execution)。
  6.  

二、The Basics(基礎)

  我們很迫切想知道如何讓Hello World module能夠工作。下面有幾個關鍵的事情要注意:

module API(http://code.angularjs.org/1.0.2/docs/api/angular.Module)

注意的提及的在<html ng-app=”myApp”>中的myApp module,它讓啟動器啟動我們定義的myApp module。

<!DOCTYPE HTML><html lang="zh-cn" ng-app="myApp"><head>  <meta charset="UTF-8">  <title>basics</title>  <style type="text/css">    .ng-cloak {      display: none;    }  </style></head><body><div class="ng-cloak">  {{'Kitty' | greet}}</div><script src="../angular-1.0.1.js" type="text/javascript"></script><script type="text/javascript">  var simpleModule = angular.module("myApp", []);  simpleModule.filter("greet", function () {    return function(name) {      return "Hello " + name + " !";    }  });</script></body></html>

三、(Recommended Setup)推薦設定

  雖然上面的例子很簡單,它不屬於大規模的應用。我們建議將自己的應用按照如下建議,拆分為多個module:

  1. service module,用於聲明service。
  2. directive module,用於聲明directive。
  3. filter module,用於聲明filter。
  4. 應用層級的module,依賴上述的module,並且包含初始化的代碼。

  這樣劃分的理由是,當我們在測試的時候,往往需要忽略那些讓測試變得困難的初始化代碼。通過將代碼分成獨立的module,在測試中就可以很容易地忽略那些代碼。這樣,我們就可以更加專註在載入相應的module進行測試。

  上面的只是一個建議,可以隨意地按照自己的需求制定。

四、Module Loading & Dependencies(模組載入和依賴)

  module是配置(configuration)的集合,執行在啟動應用的進程中應用的塊(blocks)。在它的最簡單的形式中,由兩類block組成:

  1.配置塊(configuration blocks):在provider註冊和配置的過程中執行的。只有provider和constant(常量?)可以被注入(injected)到configuration blocks中。這是為了避免出現在service配置完畢之前service就被執行的意外。

  2.運行塊(run blocks):在injector建立完成後執行,用於啟動應用。只有執行個體(instances)和常量(constants)可以被注入到run block中。這是為了避免進一步的系統配置在程式啟動並執行過程中執行。

angular.module('myModule', []).  config(function(injectables) { // provider-injector  // 這裡是config block的一個例子  // 我們可以根據需要,弄N個這樣的東東  // 我們可以在這裡注入Providers (不是執行個體,not instances)到config block裡面  }).  run(function(injectables) { // instance-injector  // 這裡是一個run block的例子  // 我們可以根據需要,弄N個這樣的東東  // 我們只能注入執行個體(instances )(不是Providers)到run block裡面});

  a) Configuration Blocks(配置塊)

  有一個方便的方法在module中,它相當於config block。例如:

angular.module('myModule', []). value('a', 123).  factory('a', function() { return 123; }).  directive('directiveName', ...).  filter('filterName', ...);// 等同於angular.module('myModule', []). config(function($provide, $compileProvider, $filterProvider) {  $provide.value('a', 123)  $provide.factory('a', function() { return 123; })  $compileProvider.directive('directiveName', ...).  $filterProvider.register('filterName', ...);});

  configuration blocks被應用的順序,與它們的註冊的順序一致。對於常量定義來說,是一種額外的情況,即放置在configuration blocks開頭的常量定義。

  b) Run Blocks(應用塊)

  run block是在angular中最接近main方法的東東。run block是必須執行,用於啟動應用的代碼。它將會在所有service配置、injector建立完畢後執行。run block通常包含那些比較難以進行單元測試的代碼,就是因為這個原因,這些代碼應該定義在一個獨立的module中,讓這些代碼可以在單元測試中被忽略。 

  c) Dependencies(依賴)

  一個module可以列出它所依賴的其他module。依賴一個module,意味著被請求(required)的module(被依賴的)必須在進行請求(requiring)module(需要依賴其他module的module,請求方)載入之前載入完成。換一種說法,被請求的module的configuration block會在請求的module的configuration block執行前執行(before the configuration blocks or the requiring module,這裡的or怎麼解釋呢?)。對於run block也是這個道理。每一個module只能夠被載入一次,即使有多個其他module需要(require)它。 

  d) Asynchronous Loading(非同步載入)

  module是管理$injector配置的方法之一,不用對載入指令碼到VM做任何事情。現在已經有現成的項目專門用於處理指令碼載入,也可以用到angular中。因為module在載入的過程中不做任何事情,它們可以按照任意的順序被載入到VM中。指令碼載入器可以利用這個特性,進行並行載入。 

            五、Unit Testing(單元測試)

  在單元測試的最簡單的形式中,其中一個是在測試中執行個體化一個應用的子集,然後運行它們。重要的是,我們需要意識到對於每一個injector,每一個module只會被載入一次。通常一個應用只會有一個injector。但在測試中,每一個測試案例都有它的injector,這意味著在每一個VM中,module會被多次載入。正確地構建module,將對單元測試有協助,正如下面的例子:

  在這個例子中,我們準備假設定義如下的module:

angular.module('greetMod', []).factory('alert', function($window) {   return function(text) {     $window.alert(text);   };}).value('salutation', 'Hello').factory('greet', function(alert, salutation) {   return function(name) {     alert(salutation + ' ' + name + '!');   };});

  讓我們寫一些測試案例:

describe('myApp', function() {  // 載入應用響應的module,然後載入指定的將$window重寫為mock版本的測試module,  // 這樣做,當進行window.alert()時,測試器就不會因被真正的alert視窗阻擋而停止  //這裡是一個在測試中覆蓋配置資訊的例子  beforeEach(module('greetMod', function($provide) {//這裡看來是要將真正的$window替換為以下的東東    $provide.value('$window', {      alert: jasmine.createSpy('alert')    });  }));     // inject()會建立一個injector,並且注入greet和$window到測試中。  // 測試不需要關心如何寫應用,只需要關注如何測試應用。  it('should alert on $window', inject(function(greet, $window) {    greet('World');    expect($window.alert).toHaveBeenCalledWith('Hello World!');  }));    // 這裡是在測試中通過行內module和inject方法來覆蓋配置的方法  it('should alert using the alert service', function() {    var alertSpy = jasmine.createSpy('alert');    module(function($provide) {      $provide.value('alert', alertSpy);    });    inject(function(greet) {      greet('World');      expect(alertSpy).toHaveBeenCalledWith('Hello World!');    });  });});
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.