什么是模块?

你可以认为一个模块就是一个app的不同部分,controllers,services,filters,directives,等。

为什么?

大多数的应用有一个main方法实例化并且链接应用的不同部分。

Angular 应用没有main方法,而是使用模块声明指定一个应用如何可以自启动。这种方式有几个优势:

  • 陈述性的过程容易理解
  • 你可以打包代码为一个可复用的模块
  • 这个模块可以以任意的顺序加载(甚至可以并行加载)因为模块是延迟执行的。
  • 单元测试只需要加载相关的模块,保持快速。
  • 端到端的测试可以使用模块去重写配置

基础训练

来看一个hello world :

<div ng-app="myApp">
  <div>
    {{ 'World' | greet }}
  </div>
</div>
// declare a module
var 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 + '!';
  };
});

注意很重要的几点:

  • 模块的API
  • <div ng-app="myApp">中引用myApp模块。这个是告诉app使用你的模块。
  • angular.module('myApp', [])中的空数组是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:

我们上面的例子很简单,它无法扩展为一个大的应用。替代它我们推荐你分解你的应用到多个模块,像这样:

  • 一个模块只用与一个功能
  • 一个模块对于每个可复用的组件(尤其是指令和过滤器)
  • 一个应用级别的模块依赖上面的模块并且包含任何的初始化代码。

我们还写了一个文档讲解如何组织大型的APP在google 。

上面的建议,根据你的需要使用。

<div ng-controller="XmplController">
  {{ greeting }}
</div>
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);
  });

模块的加载& 依赖

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 consist of a collection of two kinds of blocks:

  1. 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.
  2. 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.
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)
  // 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 run blocks
});

Configuration Blocks

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.

Run Blocks

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 service 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.

Dependencies

Modules can list other modules as their dependencies. Depending on a module implies that 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.

Asynchronous Loading

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.

Creation versus Retrieval

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.

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');

Unit Testing

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.

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.

In all of these examples we are going to assume this module deFinition:

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 tests to show how to override configuration in tests.

describe('myApp',function() {
  // 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')
    });
  }));

  // 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 inline `module` and `inject` methods.
  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!');
    });
  });
});

tips:

本文由wp2Blog导入,原文链接:http://devonios.com/angularjs-module.html

4、Angular JS 学习笔记 – 模块 [翻译中]的更多相关文章

  1. html5 拖拽及用 js 实现拖拽功能的示例代码

    这篇文章主要介绍了html5 拖拽及用 js 实现拖拽,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. amaze ui 的使用详细教程

    这篇文章主要介绍了amaze ui 的使用详细教程,本文通过多种方法给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. HTML5适合的情人节礼物有纪念日期功能

    这篇文章主要介绍了HTML5适合的情人节礼物有纪念日期功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. 如何使用Firebase在iOS上验证用户的电子邮件地址?

    我坚持使用firebase进行电子邮件验证.我四处寻找指导但没有帮助.在用户验证他的电子邮件后,我的代码仍然打印出用户尚未验证.我还在尝试习惯firebase的语法.这是我的代码:这是我注册部分的代码:解决方法您在签名之前检查了用户电子邮件是否已经过验证.这对我有用.

  5. xcode – UIAlertController Segue到不同的页面(Swift)

    我能够为我的按钮编写一个UIAlertController,它工作正常,但是当我按下YES或OK按钮时,我不知道如何切换到不同的页面.目前,YES或OK按钮无处可去.解决方法您可以在故事板中创建一个segue,控制从场景顶部的黄色视图控制器拖动到新的视图控制器.然后在检查器中为该segue指定一个标识符.您可以从代码中的处理程序中调用它.

  6. ios – 使用Swift实现应用内邮件失败

    我想使用swift来实现应用内电子邮件.当我点击按钮时,会弹出电子邮件窗口.但是,我无法发送电子邮件.此外,点击取消删除草稿后,我无法返回到原始屏幕.解决方法由于您尚未将当前视图控制器设置为myMail的mailComposeDelegate,因此未调用mailComposeController:didFinishWithResult方法.初始化myMail后,请确保添加:你会很好的去

  7. iOS Swift – 如何以编程方式为所有按钮指定默认操作

    除非通过界面生成器或以编程方式分配其他操作,否则如何为UIButton分配默认操作以显示警报?解决方法那么你想要实现的目标是什么.我已经使用UIViewController扩展并添加了一个闭包作为没有目标的按钮的目标.如果按钮没有动作,则会显示警报.我测试了它.希望这可以帮助.快乐的编码.

  8. iOS如何在任何地方点击UIAlertView?

    我想通过一键轻松将UIAlertView的任何地方关掉.我想显示一个UIAlertView没有任何按钮.我在这里有标准的UIAlertView代码,但我需要输入如何解除它,如果可能的话.用UITouch?

  9. ios – 扩展UIAlertController方便初始化警告

    当我定义一个UIAlertController方便初始化器时:并在我的UIViewController子类中的按钮操作中使用它:然后单击模拟器上的那个按钮,我收到一个警告:Attemptingtoloadtheviewofaviewcontrollerwhileitisdeallocatingisnotallowedandmayresultinundefinedbehavior(UIAlertCo

  10. ios – UIAutomation:任何方式来解雇“想使用您当前的位置”提醒?

    我的应用程序正在使用位置服务,而对于自动测试,我想要能够解除“APP想要使用当前位置”弹出窗口.但是,当我尝试使用UIAutomation脚本在Instruments中执行此操作时,我会收到此错误:这样做是有道理的,因为警报是由不同的过程产生的.但是,在这种情况下,苹果计划如何帮助人们自动化测试?

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部