There are several different types of services in angular. Each one has its own unique usage.
It is important to remember that the service is always a monomer, regardless of the type of service.
Note: A monomer is a design pattern that restricts the ability to instantiate only one object per class. No matter where we inject our service, we will always use the same instance.
Constant
Example:
App.constant (' fooconfig ', { true, "Default config2"});
Constant is a very useful service that is often used to provide default configuration in directives. So if you are creating a directive and you want to make a default configuration while passing optional parameters to the instruction, a constant is a good idea.
As a constant, the values we put into them will not change. The Contant service basically returns a basic type of value or an object.
Value
Example:
App.value (' fooconfig ', { true, ' Default config2 but it can change ' });
A value service is a bit like a constant but it can be changed. It is also often used on an instruction to configure. A value service is kind of like a scaled-down version of a factory service, which is often used to hold values but we can't calculate values in them.
We can use the Extend method of the angular object to change a value service:
App = Angular.module ("app", []); App.controller (' Mainctrl 'function($scope, Fooconfig) { = fooconfig; "I have been extended" });}); App.value (' fooconfig ', { true, ' Default config2 But it can changes "});
Factory
Example:
App.factory (' foo 'function() { var"Private"; function getprivate () { return thisisprivate; } return { variable"This was public", getprivate:getprivate };});
Or..
App.factory (' bar 'function(a) { return A * 2;});
The Factory service is the most commonly used service. It is also very easy to understand.
A factory is a service that can return any data type. There are no options for how you can create it, you just need to return something in it.
As mentioned earlier, all service types are monomers, so if we modify the foo.variable in one place, the other places will change accordingly.
Service
Example:
app.service ( ' foo ' , Span style= "color: #008000;" >function { var thisisprivate = this . variable = ; this . getprivate = function () { return thisisprivate; };});
The service service is similar to factory. The difference between them is that the service receives a constructor, so when you use it for the first time, it will automatically run new
Foo()
to instantiate an object. Be sure to remember that if you use the service in other places, it will return the same object.
In fact, the above code is equivalent to the following code:
App.factory (' Foo2 ',function() { return NewFoobar ();});functionFoobar () {varThisisprivate ="Private"; This.variable=" This was public"; This. getprivate =function() { returnthisisprivate; };}
Foobar
is a class that we instantiate in our factory and return it the first time we use it. Like the service, Foobar will only instantiate once and then the next time we use factory again, it will return to the same instance.
If we already have a class and we want to use it in service, we just need to write the following code:
App.service ('foo3', Foobar);
Provider
Provider is an enhanced version of factory. In fact, the factory code in the previous example is equivalent to the following provider code:
App.provider (' foo ',function() { return { $Get:function() { varThisisprivate ="Private"; functiongetprivate () {returnthisisprivate; } return { variable:" This was public", getprivate:getprivate}; } };});
A provider should consist of a $get function, where the content is what we want to inject into our application, so when we inject Foo into a controller, we actually inject the $get function.
Since factory is so simple, why should we use provider? Because we can configure a provider in the Config phase. So we can write the following code:
App.provider (' foo ',function() { varThisisprivate ="Private"; return{setprivate:function(newval) {thisisprivate=newval; }, $Get:function() { functiongetprivate () {returnthisisprivate; } return { variable:" This was public", getprivate:getprivate}; } };}); App. Config (function(Fooprovider) {fooprovider.setprivate (' New value from config ');});
Here we move the thisisprivate to the outside of our $get function, and then we create a setprivate to modify the thisisprivate in a config function. Why do we need to do this? Isn't it easier than adding a setter to a factory? Besides, there is another reason.
We want to inject a specific object but we want to provide a way to configure it according to our needs. For example, a service contains a resource that uses JSONP, we want to configure a specific URL to use, or we want to use a third-party service such as Restangular to allow us to configure according to our needs.
Notice that we put in the nameProvider
config function name
instead. Here, we are name
actually configuring it.
See here we have actually realized that we have done some configuration in the application, as well $routeProvider
$locationProvider
, the two are used to configure our route HTML5 mode.
Decorator
So now you've decided to use the foo
previous service, but there's still a missing greet
function that you want. Can you modify factory? The answer is NO! But you can decorate it:
App. Config (function($provide) { $provide. Decorator (' foo '),function ($delegate) { function() { return' Hello, I am a new function of ' foo '); } );
$provide is something angular used to create our service internally. If we want to use it, we can use it manually or just use the functions provided in our module (we need to use $provide to decorate). $provide has a function decorator
that allows us to decorate our service. It receives the name of the service we want to decorate and receives a $delegate in the callback function to represent our actual service instance.
Here we can do all the things we want to decorate our service. In the example above, we added a greet function to our original service. We then returned to the modified service.
After modification, we now have a function called greet in our factory.
The ability to decorate a service is very practical, especially when we want to use a third-party service, and we don't need to copy the code into our project at this point, and only need to make some changes.
Note: Constant service cannot be decorated.
Create an instance
Our services are all monomers but we can create a single factory to create a new instance. Before you go any further, remember that the services in angular are monomers and we don't want to change that. However, in the rare case where you need to generate a new instance, you can do this as follows:
//Our classfunctionPerson (JSON) {angular.extend ( This, JSON);} Person.prototype={update:function(){ //Update Content This. Name ="Dave"; This. Country ="Canada"; }}; Person.getbyid=function(ID) {//gets the information for a person by ID return NewPerson ({name:"Jesus", Country:"Spain" });};//our factory.App.factory (' Personservice ',function(){ return{getById:Person.getById};});
Here we create an Person
object that receives some JSON data to initialize the object. Then we create a function in our prototype (the function in the prototype can be used by the person's instance) and create a function directly on the person (like a class function).
So now we have a class function that will create a new object based on the ID we provide Person
, and each object can update itself. Now we just need to create a service that can use it.
Every time we call Personservice.getbyid, we are creating a new person object, so you can use the service in different controllers, even if factory is a monomer, it can generate new objects.
Summary
Service is one of the coolest features in angular. We can use many methods to create them, and we just need to find a way to meet our needs and then implement it.
This article is translated from understaning service types, the original address http://angular-tips.com/blog/2013/08/understanding-service-types/
Understanding the service types in Angularjs