One, what is module?
Many applications have one for initialization, loading (wires is this mean?). And start the application's main method. The angular application does not require a main method, which, as an alternative, provides a declarative representation of the specified purpose, describing how the application starts. There are several advantages to doing this:
- This process is described by the Declaration, and it is easier to read and understand.
- In a unit test, you do not need to load all the modules, which is helpful for writing unit tests.
- Additional module can be loaded into the scenario test to cover some settings to help the End-to-end test of the application (End-to-end testing).
- Third-party code can be packaged into angular as a reusable module.
- The module can be loaded in either order or in parallel (depending on the latency of the module execution, due to delayed nature of module execution).
Second, the Basics (foundation)
We are eager to know how to get Hello World module to work. Here are a few key things to note:
Module API (http://code.angularjs.org/1.0.2/docs/api/angular.Module)
Note the reference to the MYAPP module in the
Third, (recommended setup) recommended settings
Although the above example is very simple, it does not belong to large-scale applications. We recommend that your application be split into multiple module by following the recommendations below:
- Service module, used to declare a service.
- Directive module, used to declare directive.
- Filter module, which is used to declare filter.
- Application-level module, which relies on the above module and contains the initialized code.
The reason for this division is that when we are testing, we often need to ignore the initialization code that makes the test difficult. By splitting your code into separate module, you can easily ignore that code in a test. In this way, we can be more focused on loading the corresponding module for testing.
The above is just a suggestion that can be freely set according to your own needs.
Module Loading & Dependencies (Modular loading and dependency)
A module is a collection of configuration (configuration) that executes blocks (blocks) that are applied in the process that initiates the application. In its simplest form, it consists of two class blocks:
1. Configuration block (configuration blocks): Performed during provider registration and configuration. Only provider and constant (constants?) ) can be injected (injected) into the configuration blocks. This is to avoid the occurrence of the service being executed before the service configuration is complete.
2. Run blocks: Executes after injector is created to start the application. Only instances (instances) and constants (constants) can be injected into the run block. This is to avoid further system configuration execution while the program is running.
Angular.module (' MyModule ', []).
Config (function (injectables) {//Provider-injector///
Here is an example of Config block//
we can make n such things as needed/
We can inject providers here (not instance, not instances) into Config block
}).
Run (function (injectables) {//Instance-injector///
Here is an example of Run block//
we can make n such things as needed/
We can only inject an instance (instances) (not providers) into the run Block
});
A) Configuration Blocks (configuration block)
There is a convenient way in module, which is equivalent to config block. For example:
Angular.module (' MyModule ', []).
Value (' A ', 123).
Factory (' A ', function () {return 123;}).
directive (' directivename ', ...).
Filter (' FilterName ', ...);
Equivalent to
angular.module (' MyModule ', []).
Config (function ($provide, $compileProvider, $filterProvider) {
$provide. Value (' A ', 123)
$provide. Factory (' A ', function () {return 123;})
$compileProvider. directive (' directivename ', ...).
$filterProvider. Register (' FilterName ', ...);
};
The order in which the configuration blocks are applied is in accordance with the order in which they are registered. For a constant definition, this is an additional case, the constant definition that is placed at the beginning of the configuration blocks.
b) Run Blocks (Application Block)
Run block is the closest thing to the main method in angular. Run block is the code that must be executed to start the application. It will be executed after all service configurations, injector are created. The run block typically contains code that is more difficult to unit test, and for that reason, the code should be defined in a separate module so that the code can be ignored in unit tests.
c) Dependencies (dependent)
A module can list the other module on which it depends. Reliance on a module means that the requested (required) module (dependent) must be loaded before the request (requiring) module (a module that relies on other module, the requesting party) loads. In other words, the configuration block of the requested module executes before the configuration block of the requested module executes (before the configuration blocks or the Requiring module, what does the or explain here? )。 This is also true for run block. Each module can only be loaded once, even if there are multiple other module needs (require) it.
d) Asynchronous Loading (asynchronous loading)
Module is one way to manage $injector configuration without doing anything with the load script to the VM. There are already existing projects dedicated to processing script loading, and can also be used in angular. Because module does nothing in the load process, they can be loaded into the VM in any order. The script loader can take advantage of this feature for parallel loading.
Five, Unit Testing (units test)
In the simplest form of unit testing, one of them is to instantiate a subset of the application in the test and then run them. Importantly, we need to be aware that for each injector, each module will only be loaded once. Usually one application will have only one injector. But in the test, each test case has its injector, which means that in each VM the module is loaded multiple times. Building a module correctly will help unit tests, as in the following example:
In this example, we are prepared to assume that the following module is defined:
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 + '! ');
};}
);
Let's write some test cases:
describe (' myApp ', function () {//load the module that applies the response, and then load the specified test module that will $window be rewritten as a mock version. In this case, the tester will not stop because it is blocked by the Real alert window when Window.alert () This is an example of overwriting configuration information in a test Beforeeach (' Greetmod ', function ($
Provide) {//This seems to be to replace the real $window with the following Dongdong $provide. Value (' $window ', {alert:jasmine.createSpy (' alert ')});
}));
Inject () creates a injector and injects greet and $window into the test.
Testing does not require care about how to write applications, just focus on how to test applications.
It (' should alert on $window ", inject (function (greet, $window) {Greet (' world ');
Expect ($window. alert). Tohavebeencalledwith (' Hello world! ');
})); Here is the method of overriding the configuration through inline module and inject methods in the test 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! ');
});
});
});