anjular-service
更新日期:
首先说下service的定义,service是用来定义一些通用的处理方法的。使用dependency injection (DI)也就是angular的注入器来生成一些服务对象。
service可以做什么?,比如我们需要一个号码验证的功能,我就可以专门做个service。之后通过service来调这个通用方法。
service有两个特性:
- 它是通过依赖注入的方式实例化的,是懒加载的,只有依赖了它,它才会加载。
- 他是单例的,也就是说他只会执行一次,通过这个特性我们可以存储一些全局的对象。
单例是一种设计模式,不是很清楚的童鞋自行百度。
先看下service的基本用法:
1 2 3 4 5 6 7 | var app = angular.module('myServiceModule', []); app.factory('test', ['$window', function(win) { return {text:'hello world'}; }]); app.controller('MyController', ['$scope','test', function ($scope, test) { $scope.text = test; }]); |
我们通过factory方法定义一个service。angular的$inject(注入器)会在你下面MyController执行时,调用这个工厂方法返回{text:'hello world'}
,要注意这个工厂方法只会调用一次,单例嘛。之后我们就可以在controller里面使用了。
app,也就是模块的实例化对象不只是有factory一个方法来实现service的定义。真正说起来有下面这些:
- provider(provider) - registers a service provider with the $injector
- constant(obj) - registers a value/object that can be accessed by providers and services.
- value(obj) - registers a value/object that can only be accessed by services, not providers.
- factory(fn) - registers a service factory function, fn, that will be wrapped in a service provider object, whose $get property will contain the given factory function.
- service(class) - registers a constructor function, class that will be wrapped in a service provider object, whose $get property will instantiate a new object using the given constructor function.
这是直接拿的官网的,下面一个个解释下:
provider
这个是最底层的实现方式,实际上,其他的写法都是基于这个改写的。我们先看下它的定义service的方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //定义service: app.provider('test', { world: 'hello world', $get: function() { return {text:world} } }); //或 app.provider('test', function(){ this.world = 'hello world'; this.$get = function() { return {text:world} } }); app.controller('MyController', ['$scope','test', function ($scope, test) { $scope.text = test; }]); |
方法provider(name, provider);
,provider可以是对象,也可以是构造函数。是构造函数的话,angular的注入器会自动帮你实例化成对象。
当下面MyController执行时,注入器会调用$get方法。获取到返回值赋值给你注入的对象test。
注意的是,$get是运行时才会执行的方法,也就是说,在模块没有加载完毕时service是不可使用的。module有个方法是config,用来在模块运行前配置东西。所以使用provider有个好处是在config的时候可以使用。
factory
这个方法就是我们上面提到的,调用方法:
1 2 3 4 5 6 7 | var app = angular.module('myServiceModule', []); app.factory('test', function() { return {text:'hello world'}; }); app.controller('MyController', ['$scope','test', function ($scope, test) { $scope.text = test; }]); |
方法factory(name, factoryFunction);
,factoryFunction是个工厂方法,service实例化时会调用。
它是provider的一个变种,实现大致为:
1 2 3 4 5 6 | app.factory = function(name,factoryFunction){ app.provider('name', { $get:factoryFunction }); } |
angular会自动创建个空的provider对象,将functionFactory赋值给$get。
service
service方法service(name, constructor);
constructor是个构造函数,angular会自动调用new constructor(),实例化这个对象。
使用如下:
1 2 3 4 5 6 7 | var app = angular.module('myServiceModule', []); app.service('test', function() { this.text = 'hello world'; }); app.controller('MyController', ['$scope','test', function ($scope, test) { $scope.text = test; }]); |
实现的思路大概是:
1 2 3 4 5 6 | app.service = function(name, constructor){ app.factory(name,function(){ return new constructor(); }) } |
这么一看就清楚多了,显然service就是一个factory的再封装。与factory的区别就是,factory可以定义自己返回的服务对象的类型,可以是函数,可以是值等等。而service只能是返回的对象。
value与constant
value,见名知意,就是用来直接返回一个值,连service的construct都省了。用法也很简单:
1 2 3 4 5 6 7 | app.value('test', {text:'hello world'}); //大概的实现为: app.value = function(name,val){ app.factory(name,function(){ return val; }) } |
可以看到,基本上都是建立在provider的基础上实现的。
而且都是通过调用provider的$get实现的,这边有个问题就是由于$get是运行时才会调用,所以上面所有的service,在模块没有加载前都是不能访问到的。
不过与此对应的constant方法,也是用来定值的,与value有两个区别。
- constant用来定义常量,后面不可以修改。
- constant可以在模块没有加载完毕前使用,比如模块的config方法。
结语
可以看到service的配置方式非常灵活,其实这些方法是定义在一个叫做$provider的对象上的,模块的实例化对象上面的provider,factory等等方法都是对$provider的方法的引用。$provider不仅仅提供service的定义方式,实际上还可以定义其他的controller,directive等等等。
本来还想写个angular的模块的介绍的,但是模块没啥太多东西,推荐看这篇文章就好了。http://www.angularjs.cn/A00x
或者直接看官方英文版的https://docs.angularjs.org/guide/module
基本来说angular里面的概念都介绍了一遍了。这个系列就这样告一段落了。之后可能会再写一些单独的细节点的介绍,原理等等,有空再看看国内的jsgen的实现方式。to be continue。。。