AngularJS: Service v. Factory
2014-03-29 14:30
204 查看
From: http://www.tuicool.com/articles/zumyQv
In various AngularJS tutorials and documentation, the authors choose to use
don't explain why you would use one or the other. Few mention that
also options.
Let's see why you would use one over the other. We should also understand how providers work:
Here's the source for the
be one of three things:
function
If a function is passed in, the function is called with dependency injection and should return an object
with a
array
An array will be treated like a function using Inline Annotation . It must also return an object with
a
object
If an object is passed in, it is simply expected to have a
Whatever the second arg to
you eventually end up with an object that has a
Here's an example showing what happens:
Once you understand providers you will see that
just convenience methods for making providers.
Here's the source:
So it lets you shorten the
creation code to this:
Here's the source:
So it lets you make a factory that will instantiate a "class". For example:
The above code will instantiate
but remember that everything that uses the service will get the same instance! (which is a good thing).
Here's the source:
Using
the
Here's the source
that it's accessible during config. Here's how you use it:
Read Module Loading & Dependencies in the Modules doc for more information on usage.
If you want your function to be called like a normal function, use
If you want your function to be instantiated with the
use
the difference, use
This is the (great) documentation for each function in the AngularJS source:
A short hand for configuring services if only `$get` method is required.
A short hand for registering service of given class.
A short hand for configuring services if the `$get` method is a constant.
A constant value, but unlike {@link AUTO.$provide#value value} it can be injected into configuration function (other modules) and it is not interceptable by {@link AUTO.$provide#decorator decorator}.
In various AngularJS tutorials and documentation, the authors choose to use
serviceor
factorybut
don't explain why you would use one or the other. Few mention that
valueand
constantare
also options.
Let's see why you would use one over the other. We should also understand how providers work:
provider
Here's the source for the providermethod:
function provider(name, provider_) { if (isFunction(provider_) || isArray(provider_)) { provider_ = providerInjector.instantiate(provider_); } if (!provider_.$get) { throw Error('Provider ' + name + ' must define $get factory method.'); } return providerCache[name + providerSuffix] = provider_; }
nameis a string.
provider_can
be one of three things:
function
If a function is passed in, the function is called with dependency injection and should return an object
with a
$getmethod.
array
An array will be treated like a function using Inline Annotation . It must also return an object with
a
$getmethod.
object
If an object is passed in, it is simply expected to have a
$getmethod.
Whatever the second arg to
provideris,
you eventually end up with an object that has a
$getmethod.
Here's an example showing what happens:
// You can run this // Create a module var hippo = angular.module('hippo', []); // Register an object provider hippo.provider('awesome', { $get: function() { return 'awesome data'; } }); // Get the injector (this happens behind the scenes in angular apps) var injector = angular.injector(['hippo', 'ng']); // Call a function with dependency injection injector.invoke(function(awesome) { console.log('awesome == ' + awesome); });
Once you understand providers you will see that
factory,
service,
valueand
constantare
just convenience methods for making providers.
factory
Here's the source:function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); }
So it lets you shorten the
awesomeprovider
creation code to this:
hippo.factory('awesome', function() { return 'awesome data'; })
service
Here's the source:function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }
So it lets you make a factory that will instantiate a "class". For example:
var gandalf = angular.module('gandalf', []); function Gandalf() { this.color = 'grey'; } Gandalf.prototype.comeBack = function() { this.color = 'white'; } gandalf.service('gandalfService', Gandalf); var injector = angular.injector(['gandalf', 'ng']); injector.invoke(function(gandalfService) { console.log(gandalfService.color); gandalfService.comeBack() console.log(gandalfService.color); });
The above code will instantiate
Gandalf,
but remember that everything that uses the service will get the same instance! (which is a good thing).
value
Here's the source:function value(name, value) { return factory(name, valueFn(value)); }
Using
valuewould let you shorten
the
awesomeprovider to:
hippo.value('awesome', 'awesome data');
constant
Here's the sourcefunction constant(name, value) { providerCache[name] = value; instanceCache[name] = value; }
constantdiffers from
valuein
that it's accessible during config. Here's how you use it:
var joe = angular.module('joe', []); joe.constant('bobTheConstant', 'a value'); joe.value('samTheValue', 'a different value'); joe.config(function(bobTheConstant) { console.log(bobTheConstant); }); joe.config(function(samTheValue) { console.log(samTheValue); }); // This will fail with "Error: Unknown provider: samTheValue from joe" var injector = angular.injector(['joe', 'ng']);
Read Module Loading & Dependencies in the Modules doc for more information on usage.
In summary
If you want your function to be called like a normal function, use factory.
If you want your function to be instantiated with the
newoperator,
use
service. If you don't know
the difference, use
factory.
This is the (great) documentation for each function in the AngularJS source:
factory
A short hand for configuring services if only `$get` method is required.
service
A short hand for registering service of given class.
value
A short hand for configuring services if the `$get` method is a constant.
constant
A constant value, but unlike {@link AUTO.$provide#value value} it can be injected into configuration function (other modules) and it is not interceptable by {@link AUTO.$provide#decorator decorator}.
相关文章推荐
- AngularJS中的Provider们:Service和Factory等的区别
- AngularJS 之 Factory vs Service vs Provider
- AngularJS 服务层的三种创建方式(provider,factory,service)
- Angularjs中provider,factory和service的不同
- AngularJS中的Provider们:Service和Factory等的区别
- AngularJS: Service v. Factory
- angularJS 服务--$provide里factory、service方法
- angularjs中service,factory,provider的区别
- angularJs中service的三种方法以及区别(factory,service,provider三者的区别)
- 深究AngularJS——自定义服务详解(factory、service、provider)
- angularjs中provider、factory和service三者的写法与区别
- Angularjs中provider,factory和service的不同
- 第17篇:AngularJS中的Provider们:Service和Factory等的区别
- 深究AngularJS——自定义服务详解(factory、service、provider)
- [转]angularjs的provider~ (Provider, Value, Constant, Service, Factory, Decorator)
- 第30篇:AngularJS 中的 factory、 service 和 provider区别
- AngularJS使用factory和service的方法
- AngularJS中的Provider们:Service和Factory等的区别
- AngularJS: Factory vs Service vs Provider
- 《AngularJS》------自定义服务 provider、service、factory