Angular JS factory vs service vs provider by example
I know this question has been asked and answers have been given. But I learn best through practical examples and I came across code that I didn't fully understand.
I'm referring to Angular Strap which is an awesome set of directives for cool user interactions: http://mgcrea.github.io/angular-strap/
I was looking at the code for the tooltip feature and saw that the author was using a provider to expose functionality. Could he have also used a service or a factory to do the same job? Or was a provider necessary?
Here is the link to the code: https://github.com/mgcrea/angular-strap/blob/master/src/tooltip/tooltip.js#L28
Thank you
Short answer: The author chose Provider to make the defaults 'read-only'. The code could still work if they hadn't used Provider, but Provider is cleaner and 'safer'
Provider
, Service
, and Factory
are all the same basic thing in Angular, just with different APIs; Provider
can kinda be thought of as the 'base' element, but they all have the same end purpose: to create an Angular injectable. Each of those injectables has a Provider that provides the blueprint (Angular looks for a $get
method), and a Singleton instance the provider generates. If you use Factory
or Service
, Angular does work behind the scenes so you don't need to know all the details; you'll just have a really boring Provider
that only does the basics. However, if you use Provider
yourself, you can put extra properties and functions on it in your declaration.
You can inject Providers
into a module's config()
method, which is run before any of the Singletons are created. Try looking here for a longer explanation.
In AngularStrap, the author puts a 'defaults' object on the Provider. The author expects you to modify that object in your module's config()
method, and then Angular will generate the Singleton. However, the 'defaults' object is not on the Singleton , so you can't change the defaults once the app is 'running'. Even if you inject the Provider
again somewhere and change 'default's again, Angular won't re-make your Singleton, so the defaults effectively become 'read-only'. This is a good practice to prevent code from making unwanted changes, especially when you have multiple people in the same code, or you know other people will be using your module.
You may see other code that doesn't work like that... maybe another app just uses a factory
, and puts the 'defaults' object on that factory. It would still 'work', and the code would look a lot like it does currently. However, because 'defaults' would be directly on the Singleton, your code could change these settings at ANY point if somebody wrote code to do it. Now you've got to leave comments and documentation explaining when to change the defaults, when NOT to change the defaults, and so on; for 99% of cases, the defaults never need to change once the app is running, so using Provider
and module.config()
is safe and straightforward.
While the documentation is correct that there are special cases to use each I think it's also important to answer that they are all the same thing.
The factory
is a specialized version of provider
that in some cases let's you accomplish the same thing using less code. In turn a service
and value
are special cases of factory
. And constant
is a special case of value
.
Here is an image that shows you at a glance what I mean:
providers factories value and service are the same thing http://www.simplygoodcode.com/wp-content/uploads/2015/11/angularjs-provider-service-factory-highlight.png
You can get more details on the blog the image is from: http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
There's also another question on Stack Overflow with similiar details at: https://stackoverflow.com/a/33805462/984780
According to the official Angular Documentation:
There are five recipe types.
The most verbose, but also the most comprehensive one is a Provider recipe. The remaining four recipe types — Value, Factory, Service and Constant — are just syntactic sugar on top of a provider recipe.
So, in essence, building a Service and building a Provider are identical, assuming you don't need to access some of the advanced settings. They go on to say:
You should use the Provider recipe only when you want to expose an API for application-wide configuration that must be made before the application starts.
and here is a table:
Features / Recipe type
Factory Service Value Constant Provider can have dependencies yes yes no no yes uses type friendly injection no yes yes* yes* no object available in config phase no no no yes yes** can create functions yes yes yes yes yes can create primitives yes no yes yes yes
* at the cost of eager initialization by using new operator directly
** the service object is not available during the config phase, but the provider instance is.
链接地址: http://www.djcxy.com/p/77900.html上一篇: 使用服务的控制器之间的角度共享数据