aboutsummaryrefslogtreecommitdiffstats
path: root/docs/content
diff options
context:
space:
mode:
authorBrian Ford2014-03-03 12:51:56 -0800
committerBrian Ford2014-03-03 12:52:03 -0800
commitd07101dec08a698932ef0aa2fc36316d6f7c4851 (patch)
tree433bc9c73d729947642304c49a6340ea32efc6e7 /docs/content
parent2206b9935922b5451f13d60830490a4b9bef8548 (diff)
downloadangular.js-d07101dec08a698932ef0aa2fc36316d6f7c4851.tar.bz2
docs(guide/module): improve clarity
Diffstat (limited to 'docs/content')
-rw-r--r--docs/content/guide/module.ngdoc135
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) {