第 11 章 AngularJS模块加载

第 11 章 AngularJS模块加载

AngularJS模块可以在被加载和执行之前对其自身进行配置。我们可以在应用的加载阶段应用不同的逻辑组。

11.1 配置

在模块的加载阶段,AngularJS会在提供者注册和配置的过程中对模块进行配置。在整个AngularJS的工作流中,这个阶段是唯一能够在应用启动前进行修改的部分。

angular.module('myApp', [])
  .config(function($provide) {
  });

这本书的大部分内容都在使用config()函数的语法糖,并在配置阶段执行。例如,我们在某个模块之上创建一个服务或指令时:

angular.module('myApp', [])
.factory('myFactory', function(){
    var service = {};
    return service;
})
.directive('myDirective', function(){
    return {
        template: '<button>Click me</button>'
    }
})

AngularJS会在编译时执行这些辅助函数。它们在功能上等同于下面的写法:

angular.module('myApp', [])
.config(function($provide ,$compileProvider) {
    $provide.factory('myFactory', function() {
        var service = {};
        return service;
    });
    $compileProvider.directive('myDirective', function() {
        return {
            template: '<button>Click me</button>'
        };
    });
});

需要特别注意,AngularJS会以这些函数书写和注册的顺序来执行它们。也就是说我们无法注入一个尚未注册的提供者。

唯一例外的是constant()方法,这个方法总会在所有配置块之前被执行。

当对模块进行配置时,需要格外注意只有少数几种类型的对象可以被注入config()函数中:提供者和常量。如果我们将一个服务注入进去,会在真正对其进行配置之前就意外地把服务实例化了。

这种对配置服务进行严格限制的另外一个副作用就是,我们只能注入用provider()语法构建的服务,其他的则不行。

更多关于用provider()语法构建服务的内容,请查看第14章。

这些config()代码块可以对我们的服务进行自定义配置,例如设置API密钥或自定义URL等。

也可以定义多个配置块,它们会按照顺序执行,这样就可以将应用不同阶段的配置代码集中在不同的代码块中。

angular.module('myApp', ['ngRoute'])
.config(function($routeProvider) {
    $routeProvider.when('/', {
        controller: 'WelcomeController',
        template: 'views/welcome.html'
    });
})
.config(function(ConnectionProvider) {
    ConnectionProvider.setApiKey('SOME_API_KEY');
});

config()函数接受一个参数。

  • configFunction(函数):AngularJS在模块加载时会执行这个函数。

1.3及之后的版本,所有的.config块都在.provider运行之后运行。这意味着不能使用.config来配置“下游”provider。在任何情况下这都不是一种好的做法,在v1.3+中这么做是行不通的。

11.2 运行块

和配置块不同,运行块在注入器创建之后被执行,它是所有AngularJS应用中第一个被执行的方法。

运行块是AngularJS中与main方法最接近的概念。运行块中的代码块通常很难进行单元测试,它是和应用本身高度耦合的。

运行块通常用来注册全局的事件监听器。例如,我们会在.run()块中设置路由事件的监听器以及过滤未经授权的请求。

假设我们需要在每次路由发生变化时,都执行一个函数来验证用户的权限,放置这个功能唯一合理的地方就是run方法:

angular.module('myApp', ['ngRoute'])
.run(function($rootScope, AuthService) {
    $rootScope.$on('$routeChangeStart', function(evt, next, current) {
        // 如果用户未登录
        if (!AuthService.userLoggedIn()) {
            if (next.templateUrl === "login.html") {
                // 已经转向登录路由因此无需重定向
            } else {
                $location.path('/login');
            }
        }
    });
});

run()函数接受一个参数。

  • initializeFn(函数)AngularJS在注入器创建后会执行这个函数。

目录

  • 版权声明
  • 在微博上分享这本书
  • 献词
  • 译者序
  • 引言
  • 第 1 章 初识AngularJS
  • 第 2 章 数据绑定和第一个AngularJS Web应用
  • 第 3 章 模块
  • 第 4 章 作用域
  • 第 5 章 控制器
  • 第 6 章 表达式
  • 第 7 章 过滤器
  • 第 8 章 指令简介
  • 第 9 章 内置指令
  • 第 10 章 指令详解
  • 第 11 章 AngularJS模块加载
  • 第 12 章 多重视图和路由
  • 第 13 章 依赖注入
  • 第 14 章 服务
  • 第 15 章 同外界通信:XHR和服务器通信
  • 第 16 章 XHR实践
  • 第 17 章 promise
  • 第 18 章 服务器通信
  • 第 19 章 测试
  • 第 20 章 事件
  • 第 21 章 架构
  • 第 22 章 Angular动画
  • 第 23 章 digest循环和$apply
  • 第 24 章 揭秘Angular
  • 第 25 章 Angular精华扩展
  • 第 26 章 移动应用
  • 第 27 章 本地化
  • 第 28 章 缓存
  • 第 29 章 安全性
  • 第 30 章 AngularJS和IE浏览器
  • 第 31 章 构建Angular Chrome应用
  • 第 32 章 优化Angular应用
  • 第 33 章 调试AngularJS
  • 第 34 章 下一步
  • 第 35 章 总结
  • ngbook-2014年10月更新