diff options
| author | Brian Ford | 2014-03-03 12:51:56 -0800 | 
|---|---|---|
| committer | Brian Ford | 2014-03-03 12:52:03 -0800 | 
| commit | d07101dec08a698932ef0aa2fc36316d6f7c4851 (patch) | |
| tree | 433bc9c73d729947642304c49a6340ea32efc6e7 | |
| parent | 2206b9935922b5451f13d60830490a4b9bef8548 (diff) | |
| download | angular.js-d07101dec08a698932ef0aa2fc36316d6f7c4851.tar.bz2 | |
docs(guide/module): improve clarity
| -rw-r--r-- | docs/content/guide/module.ngdoc | 135 | 
1 files changed, 71 insertions, 64 deletions
| diff --git a/docs/content/guide/module.ngdoc b/docs/content/guide/module.ngdoc index 747209c2..e2925584 100644 --- a/docs/content/guide/module.ngdoc +++ b/docs/content/guide/module.ngdoc @@ -4,27 +4,27 @@  # What is a Module? -Most applications have a main method which instantiates, wires, and bootstraps the application. +You can think of a module as a container for the different parts of your app – controllers, +services, filters, directives, etc. + +# Why? + +Most applications have a main method that instantiates and wires together the different parts of +the application. +  Angular apps don't have a main method. Instead modules declaratively specify how an application  should be bootstrapped. There are several advantages to this approach: -  * The process is more declarative which is easier to understand -  * In unit-testing there is no need to load all modules, which may aid in writing unit-tests. -  * Additional modules can be loaded in scenario tests, which can override some of the -    configuration and help end-to-end test the application -  * Third party code can be packaged as reusable modules. -  * The modules can be loaded in any/parallel order (due to delayed nature of module execution). +  * The declarative process is easier to understand. +  * You can package code as reusable modules. +  * The modules can be loaded in any order (or even in parallel) because modules delay execution. +  * Unit tests only have to load relevant modules, which keeps them fast. +  * End-to-end tests can use modules to override configuration.  # The Basics -Ok, I'm in a hurry. How do I get a Hello World module working? - -Important things to notice: - -  * {@link angular.Module Module} API -  * Notice the reference to the `myApp` module in the `<html ng-app="myApp">`, it is what -    bootstraps the app using your module. +I'm in a hurry. How do I get a Hello World module working?  <example module='myApp'>    <file name="index.html"> @@ -47,6 +47,13 @@ Important things to notice:    </file>  </example> +Important things to notice: + +  * The {@link angular.Module Module} API +  * The reference to `myApp` module in `<html ng-app="myApp">`. +    This is what bootstraps the app using your module. +  * The empty array in `angular.module('myApp', [])`. +    This array is the list of modules `myApp` depends on.  # Recommended Setup @@ -54,18 +61,15 @@ Important things to notice:  While the example above is simple, it will not scale to large applications. Instead we recommend  that you break your application to multiple modules like this: -  * A service module, for service declaration -  * A directive module, for directive declaration -  * A filter module, for filter declaration -  * And an application level module which depends on the above modules, and which has +  * A module for each feature +  * A module for each reusable component (especially directives and filters) +  * And an application level module which depends on the above modules and contains any      initialization code. -The reason for this breakup is that in your tests, it is often necessary to ignore the -initialization code, which tends to be difficult to test. By putting it into a separate module it -can be easily ignored in tests. The tests can also be more focused by only loading the modules -that are relevant to tests. +We've also written a document on how we organize large apps at Google and on how to write +reusable components. -The above is only a suggestion, so feel free to tailor it to your needs. +The above is a suggestion. Tailor it to your needs.  <example module='xmpl'>    <file name="index.html"> @@ -133,19 +137,19 @@ angular.module('myModule', []).      // 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 the config blocks. +    // into config blocks.    }).    run(function(injectables) { // 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 the run blocks +    // into run blocks    });  ```  ## Configuration Blocks -There are some convenience methods on the module which are equivalent to the config block. For +There are some convenience methods on the module which are equivalent to the `config` block. For  example:  ```js @@ -166,8 +170,10 @@ angular.module('myModule', []).    });  ``` -The configuration blocks get applied in the order in which they are registered. The only exception -to it are constant definitions, which are placed at the beginning of all configuration blocks. +<div class="alert alert-info"> +When bootstrapping, first Angular applies all constant definitions. +Then Angular applies configuration blocks in the order same order they were registered. +</div>  ## Run Blocks @@ -198,72 +204,73 @@ Beware that using `angular.module('myModule', [])` will create the module `myMod  existing module named `myModule`. Use `angular.module('myModule')` to retrieve an existing module.  ```js -  var myModule = angular.module('myModule', []); -   -  // add some directives and services -  myModule.service('myService', ...); -  myModule.directive('myDirective', ...); +var myModule = angular.module('myModule', []); + +// add some directives and services +myModule.service('myService', ...); +myModule.directive('myDirective', ...); -  // overwrites both myService and myDirective by creating a new module -  var myModule = angular.module('myModule', []); +// overwrites both myService and myDirective by creating a new module +var myModule = angular.module('myModule', []); -  // throws an error because myOtherModule has yet to be defined -  var myModule = angular.module('myOtherModule'); +// throws an error because myOtherModule has yet to be defined +var myModule = angular.module('myOtherModule');  ```  # Unit Testing -In its simplest form a unit test is a way of instantiating a subset of the application in test and -then applying a stimulus to it. It is important to realize that each module can only be loaded -once per injector. Typically an app has only one injector. But in tests, each test has its own -injector, which means that the modules are loaded multiple times per VM. Properly structured -modules can help with unit testing, as in this example: +A unit test is a way of instantiating a subset of an application to apply stimulus to it. +Small, structured modules help keep unit tests concise and focused. + +<div class="did you know..."> +Each module can only be loaded once per injector. +Usually an Angular app has only one injector and modules are only loaded once. +Each test has its own injector and modules are loaded multiple times. +</div>  In all of these examples we are going to assume this module definition:  ```js -  angular.module('greetMod', []). +angular.module('greetMod', []). -    factory('alert', function($window) { -      return function(text) { -        $window.alert(text); -      } -    }). +  factory('alert', function($window) { +    return function(text) { +      $window.alert(text); +    } +  }). -    value('salutation', 'Hello'). +  value('salutation', 'Hello'). -    factory('greet', function(alert, salutation) { -      return function(name) { -        alert(salutation + ' ' + name + '!'); -      } -    }); +  factory('greet', function(alert, salutation) { +    return function(name) { +      alert(salutation + ' ' + name + '!'); +    } +  });  ``` -Let's write some tests: +Let's write some tests to show how to override configuration in tests.  ```js  describe('myApp', function() { -  // load the relevant application modules then load a special -  // test module which overrides the $window with a mock version, -  // so that calling window.alert() will not block the test -  // runner with a real alert box. This is an example of overriding -  // configuration information in tests. +  // load application module (`greetMod`) then load a special +  // test module which overrides `$window` with a mock version, +  // so that calling `window.alert()` will not block the test +  // runner with a real alert box.    beforeEach(module('greetMod', function($provide) {      $provide.value('$window', {        alert: jasmine.createSpy('alert')      });    })); -  // The inject() will create the injector and inject the greet and -  // $window into the tests. The test need not concern itself with -  // wiring of the application, only with testing it. +  // inject() will create the injector and inject the `greet` and +  // `$window` into the tests.    it('should alert on $window', inject(function(greet, $window) {      greet('World');      expect($window.alert).toHaveBeenCalledWith('Hello World!');    }));    // this is another way of overriding configuration in the -  // tests using an inline module and inject methods. +  // tests using inline `module` and `inject` methods.    it('should alert using the alert service', function() {      var alertSpy = jasmine.createSpy('alert');      module(function($provide) { | 
