Mastering Web Application Development with AngularJS 读书笔记(三)
第一章笔记 (三)
一、Factories
factory 方法是创建对象的另一种方式,与service相比更灵活,因为可以注册可任何任意对象创造功能。例如:
myMod.factory('notificationsService',function(notificationsArchive){ var MAX_LEN = 10; var notifications = []; return { push:function (notification) { var notificationToArchive; var newLen = notifications.unshift(notification); //push 方法现在依赖闭包了 if (newLen > MAX_LEN) { notificationToArchive = this.notifications.pop(); notificationsArchive.archive(notificationToArchive); } }, // other methods of the NotificationsService };
AngularJS用提供的factory方法来注册对象返回。factory方法是常用的把对象带入依赖注入系统的方式。
我们可以提供一个域来模拟私有变量。当一个给定的服务,需要隐藏一些细节的时候很有用。
二、常量 Constants
常量可以在模型这个层级被定义并且被当作其他合作对象被注入。
myMod.factory('notificationsService', function (notificationsArchive, MAX_LEN) {
…
//creation logic doesn't change
});
我们可以在 notificationsService外面配置一些值。比如:myMod.constant('MAX_LEN', 10);
常量在创建跨不同应用的被重用的服务时很有用。唯一的缺点是,只要服务被表示为依赖常量,这个常量就必须被赋值。有时候,可以给常量设定默认的值,根据情况再去修改。
三、Providers
到目前位置,所描述的注册方法,都是最通用的特殊情况,所有这些的终极版本是 provider
myMod.provider('notificationsService', function () { var config = { maxLen : 10 }; var notifications = []; return { setMaxLen : function(maxLen) { config.maxLen = maxLen || config.maxLen; }, $get : function(notificationsArchive) { return { push:function (notification) { … if (newLen > config.maxLen) { … } }, // other methods go here } }; });
首先,provider是个方法它必须返回一个对象包含$get属性。$get属性是一个工厂方法,当被调用的时候返回一个service实例。
其次,从provider方法中返回的对象有额外的方法和属性。
更重要的是,它可以有更多的配置逻辑,当我们的服务可以暴漏更多的配置方法而不仅仅是配置值。
四、模型生命周期 Modules lifecyle
AngularJS中module的生命周期有两个阶段:
A、配置阶段:该阶段所有的方法(recipes)被收集和配置。
B、运行阶段:该阶段我们可以运行任何后实例逻辑(post-instantiation logic)
五、配置阶段
Providers 只有在配置阶段可以配置。例如:
myMod.config(function(notificationsServiceProvider){
notificationsServiceProvider.setMaxLen(5);
});
重要的是注意到一个依赖 notificationsServiceProvider 对象带Provider后缀,代表该方法(recipes)要被执行。
配置阶段允许我们做的是最后时刻的调整对象的创建公式。
六、运行阶段
运行阶段允许我们登记任何根据应用程序的引导应当被执行的工作。相当于其他编程语言中的主方法。
最大的区别是AngularJS模块可以有很多配置和运行块。在这个意义上说,没有单一的入口点。(正在运行的程序是一个真正的协作对象的集合)
比如,显示程序运行的初始时间:
angular.module('upTimeApp', []).run(function($rootScope) {
$rootScope.appStarted = new Date();
});
Application started at: {{appStarted}}
注意: 保守地说$rootScope实例只能用来定义一些新的属性,并且只有那些在很多模版中可用的属性。
七、服务和他们跨模块的可见性 Services and their visibility across modules
在子模块中定义的服务可以注入到伏模块中的服务。比如:
angular.module('app', ['engines']) .factory('car', function ($log, dieselEngine) { return { start: function() { $log.info('Starting ' + dieselEngine.type); }; } }); angular.module('engines', []) .factory('diesel1Engine', function () { return { type: 'diesel' }; });
服务定义在相邻模块也是彼此可见的。换句话说,模型的层级结构不影响服务对其他模型的可见。当AngularJS引导一个应用程序的时候,它把程序中所有模型的服务都联合在一起,在全局的命名空间下。
在AngularJS应用中,某命名有且只能对应一个服务。在模型高层级定义的服务会重写在子模型中的同名服务。