https://docs.angularjs.org/guide/module
You can think of a module as a container for the different parts of your app – controllers, services, filters, directives, etc.
Module 是什么?
你可以把Module想象成controllers, services, filters, directives, 等的容器。
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 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.
为什么?
大多数应用有一个main方法去实例化和包含应用的不同部分。(可以参考C语言)。
angularjs 的应用没有一个main方法。取而代之使用modules声明应用如何启动。
这样做有以下优点:
声明过程更容易理解
你可以把代码打包成可重用的modules.
modules可以以任何顺序加载(甚至是并行),因为modules是延时执行的。
单元测试只需要加载相关的modules,这样是它们更快。
端到端的测试可以使用modules覆盖配置
I'm in a hurry. How do I get a Hello World module working?
基础
我着急。我怎样使Hello World modules 运行起来哪?
index.html
<div ng-app="myApp"> <div> {{ 'World' | greet }} </div> </div>
script.js
// declare a modulevar myAppModule = angular.module('myApp', []); // configure the module. // in this example we will create a greeting filter myAppModule.filter('greet', function() { return function(name) { return 'Hello, ' + name + '!'; }; });
protractor.js
it('should add Hello to the name', function() { expect(element(by.binding("'World' | greet")).getText()).toEqual('Hello, World!'); });
display :
Hello, World!
Important things to notice:
The Module API
The reference to myApp
module in <div 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.
要注意的重要事情:
Module的API
myApp module的应用在 <div ng-app="myApp">。它使用你的modules启动你的app
angular.module('myApp', [])
. 中的空数组。这个数组是modules myApp
的依赖列表。
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 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.
We've also written a document on how we organize large apps at Google.
The above is a suggestion. Tailor it to your needs.
推荐的步骤
上面的例子很简单,它难以扩展到大的应用。我们建议你把应用分解成多个modules 像下面这样:
index.html
<div ng-controller="XmplController"> {{ greeting }} </div>
script.js
angular.module('xmpl.service', []) .value('greeter', { salutation: 'Hello', localize: function(localization) { this.salutation = localization.salutation; }, greet: function(name) { return this.salutation + ' ' + name + '!'; } }) .value('user', { load: function(name) { this.name = name; } }); angular.module('xmpl.directive', []); angular.module('xmpl.filter', []); angular.module('xmpl', ['xmpl.service', 'xmpl.directive', 'xmpl.filter']) .run(function(greeter, user) { // This is effectively part of the main method initialization code greeter.localize({ salutation: 'Bonjour' }); user.load('World'); }) .controller('XmplController', function($scope, greeter, user){ $scope.greeting = greeter.greet(user.name); });
protractor.js
it('should add Hello to the name', function() { expect(element(by.binding("'World' | greet")).getText()).toEqual('Hello, World!'); });
A module is a collection of configuration and run blocks which get applied to the application during the bootstrap process. In its simplest form the module consists of a collection of two kinds of blocks:
Configuration blocks - get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.
Run blocks - get executed after the injector is created and are used to kickstart the application. Only instances and constants can be injected into run blocks. This is to prevent further system configuration during application run time.
Module 加载 & 依赖
一个module 是被应用在应用启动过程中配置和运行块的集合。最简单的Module有两类块组成:
配置块 - 在provider的注册和配置阶段得到执行。只有providers和constants 可以被注入到配置块。这是为了阻止services意外的实例化在配置完成前。
运行块 - injector被创建和应用开始的被执行。只有providers和constants 可以被注入到配置块。这是为了阻止在应用运行之后的系统配置。
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) 只能注入Providers (不是实例) // 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) 只能注入实例(不是Providers) // into run blocks });
译言: config 只能注入Providers (不是实例) , 只能注入实例(不是Providers)
There are some convenience methods on the module which are equivalent to the config
block. For example:
配置块
有一些方便的方法达到同样的效果。例如
angular.module('myModule', []). value('a', 123). factory('a', function() { return 123; }). directive('directiveName', ...). filter('filterName', ...); // is same as angular.module('myModule', []). config(function($provide, $compileProvider, $filterProvider) { $provide.value('a', 123); $provide.factory('a', function() { return 123; }); $compileProvider.directive('directiveName', ...); $filterProvider.register('filterName', ...); });
When bootstrapping, first Angular applies all constant definitions. Then Angular applies configuration blocks in the same order they were registered.
启动时,首先应用所有的constant 定义。然后Angularjs 应用配置块按照它们注册的顺序。
Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the services have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests.
运行块
运行块是Angularjs中最接近Main方法的。运行块是启动程序的一段代码。它被执行当所有的服务被配置和注入器被创建后。典型的运行块包含难以测试,基于这个原因,应该在隔离模块中声明,以使它们可以在单元测试被忽略。
Modules can list other modules as their dependencies. Depending on a module implies that the required module needs to be loaded before the requiring module is loaded. In other words the configuration blocks of the required modules execute before the configuration blocks of the requiring module. The same is true for the run blocks. Each module can only be loaded once, even if multiple other modules require it.
Modules 可以是其他Modules的依赖。依赖一个module意味着被依赖的module需要在依赖它的module加载前加载。换句话说被依赖module的配置块的代码在依赖它的module的配置块的代码执行前执行。对于运行块也一样。一个module只加载一次,即便有多个其他module依赖它。
Modules are a way of managing $injector configuration, and have nothing to do with loading of scripts into a VM. There are existing projects which deal with script loading, which may be used with Angular. Because modules do nothing at load time they can be loaded into the VM in any order and thus script loaders can take advantage of this property and parallelize the loading process.
异步加载
Modules 是一种管理注入配置的方法,和加载脚本到虚拟机无关。有已经存在的处理脚本加载的项目,也许被Angular是用。因为modules 在加载的时候什么也不做,他们可以以任何顺序加载到虚拟机,因此script加载器可以利用这个属性和并行加载过程。
Beware that using angular.module('myModule', [])
will create the module myModule
and overwrite any existing module namedmyModule
. Use angular.module('myModule')
to retrieve an existing module.
创建于回复
注意使用angular.module('myModule', [])
创建myModule
同时所有存在的同名module将被覆盖。使用angular.module('myModule')
去恢复存在的module。
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', []); // throws an error because myOtherModule has yet to be defined var myModule = angular.module('myOtherModule');