AngularJs 的 service 是基于 service 工厂创建出来的单一对象,而 service 工厂均是由 service provider 创建的。service provider 是一个构造函数,当 service provider 被实例化的时候,一定会包含 $get 属性,这个属性就是 service factory 所要提供的所有方法的函数。
那 $provider 在调用时发生了什么?
当在 controller 或者是 component 中引用 $provider 的时候,$injector 会根据 name 找到正确的 $provider ,然后实例化它、调用 $get 并返回他的值,而这个值就是 service 的实例。
2. $provider 有哪些表现形式?
$provider 针对注入功能的不同提供了一些简写方法:
provider
factory
service
constant
value
decorator
本文的主要内容仅针对 service , factory 和 provider 这三种形式的 $provider。
可以理解为,factory 和 service 的 $provider 都是在 provider 方法基础上做的进一步封装。
// 声明名为 test4provider 的 provider
demo.provider('test4provider', function () {
// 赋予 test4provider 构造函数一个成员方法 sayHello
this.sayHello = function () {
console.log('test4provider say hello');
};
// $get 方法赋值是必不可少的,这是该 provider 可注入到其他 controller 或 component 的先决条件
this.$get = ['$scope', function ($scope) {
return {
sayHi: function () {
console.log('test4provider\'s $get say hi!');
}
};
}]
})
demo.config('demo.config', ['test4providerProvider', function (test4provider) {
// { sayHello: function() {...}, $get: function() { ... } }
console.log(test4provider);
// test4provider say hello
test4provider.sayHello();
// test4provider's $get say hi!
test4provider.$get().sayHi();
}])
demo.controller('demo.ctrl', ['test4provider', function(test4provider) {
// Error: sayHello is not a function
test4provider.sayHello();
// 调用 test4provider 的服务项 sayHi
test4provider.sayHi();
}])
3.2 factory(name, $getFn)
注册 factory 的服务。
// 声明名为 test4factory 的 factory
demo.factory('test4factory', function () {
return {
sayHi: function () {
console.log('test4factory\'s $get say hi!');
}
};
})
demo.config('demo.config', ['test4factoryProvider', function (test4factory) {
// { $get: function() { ... } }
console.log(test4factory);
// Error: sayHello is not a function
test4provider.sayHello();
// test4factory $get say hi!
test4factory.$get().sayHi();
}])
demo.controller('demo.ctrl', ['test4factory', function(test4factory) {
// Error: sayHello is not a function
test4factory.sayHello();
// 调用 test4factory 的 sayHi
test4factory.sayHi();
}])
3.3 service(name, constructor)
注册服务的构造函数。
var Say = function () {};
Say.$inject = ['$scope'];
Say.prototype.sayHi = function () {
console.log('Say hi!');
};
// 声明名为 test4service 的 service
demo.service('test4service', Say);
demo.config('demo.config', ['test4serviceProvider', function (test4service) {
// { $get: function() { ... } }
console.log(test4service);
// Error: sayHello is not a function
test4service.sayHello();
// 通过 new 关键字创建一个 test4service 的 $get 的实例,然后调用 sayHi 方法
(new test4service.$get()).sayHi(); // say hi!
}])
demo.controller('demo.ctrl', ['test4service', function(test4service) {
// Error: sayHello is not a function
test4service.sayHello();
// 调用 test4service 的原型方法 sayHi
test4service.sayHi();
}])
4. 总结
OK,到这里你可能对 provider, factory 和 service 有了大致的了解,那么让我们来总结下:
1. 这三种方法都可以在 config 里注入服务,不过有些区别:
provider 的使用方式最灵活,既可以访问其构造函数内部的成员方法,也可以以调用的方式直接访问 $get 属性,当然也可以使用 new 关键字实例化 $get(前提是 $get 对应的是构造函数);
1. 什么是
$provider
?$provider
是 AngularJs 的提供的一种服务(service),基于$injector
模块将许多方法注册到组件、config 和 filter 中。那什么是 AngularJs 的 service 呢?
那
$provider
在调用时发生了什么?2.
$provider
有哪些表现形式?$provider
针对注入功能的不同提供了一些简写方法:provider
factory
service
constant
value
decorator
本文的主要内容仅针对
service
,factory
和provider
这三种形式的$provider
。3. 如何使用?
若要
$provider
生效,那么需要将其挂在到某一个module
下:本文将以
var demo
作为主要的演示模块。3.1
provider(name, constructor)
注册一个
provider
的构造函数,通过实例化这个构造函数可以注入 factory 或 service。可以理解为,
factory
和service
的$provider
都是在provider
方法基础上做的进一步封装。3.2
factory(name, $getFn)
注册
factory
的服务。3.3
service(name, constructor)
注册服务的构造函数。
4. 总结
OK,到这里你可能对
provider
,factory
和service
有了大致的了解,那么让我们来总结下:1. 这三种方法都可以在
config
里注入服务,不过有些区别:provider
的使用方式最灵活,既可以访问其构造函数内部的成员方法,也可以以调用的方式直接访问$get
属性,当然也可以使用new
关键字实例化$get
(前提是$get
对应的是构造函数);factory
在config
中只能访问其$get
方法,并且仅能以函数调用的方式获取$get
方法的返回值,其值为声明factory
时的方法;service
在config
中也只能访问$get
方法,但是必须要以new
关键字来创建实例后访问其实例对象。2. 这三种方法都可以在
controller
或component
中注入服务:provider
,无法在controller
和component
中访问构造函数的成员对象,只能访问调用$get
方法后的返回值。