angular.service vs angular.factory
I have seen both angular.factory() and angular.service() used to declare services; however, I cannot find angular.service
anywhere in official documentation.
What is the difference between the two methods? Which should be used for what (assuming they do different things)?
angular.service('myService', myServiceFunction);
angular.factory('myFactory', myFactoryFunction);
I had trouble wrapping my head around this concept until I put it to myself this way:
Service : the function that you write will be new -ed:
myInjectedService <---- new myServiceFunction()
Factory : the function (constructor) that you write will be invoked :
myInjectedFactory <--- myFactoryFunction()
What you do with that is up to you, but there are some useful patterns...
Such as writing a service function to expose a public API:
function myServiceFunction() {
this.awesomeApi = function(optional) {
// calculate some stuff
return awesomeListOfValues;
}
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.awesome = myInjectedService.awesomeApi();
Or using a factory function to expose a public API:
function myFactoryFunction() {
var aPrivateVariable = "yay";
function hello() {
return "hello mars " + aPrivateVariable;
}
// expose a public API
return {
hello: hello
};
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.hello = myInjectedFactory.hello();
Or using a factory function to return a constructor:
function myFactoryFunction() {
return function() {
var a = 2;
this.a2 = function() {
return a*2;
};
};
}
---------------------------------------------------------------------------------
// Injected in your controller
var myShinyNewObject = new myInjectedFactory();
$scope.four = myShinyNewObject.a2();
Which one to use?...
You can accomplish the same thing with both. However, in some cases the factory gives you a little bit more flexibility to create an injectable with a simpler syntax. That's because while myInjectedService must always be an object, myInjectedFactory can be an object, a function reference, or any value at all. For example, if you wrote a service to create a constructor (as in the last example above), it would have to be instantiated like so:
var myShinyNewObject = new myInjectedService.myFunction()
which is arguably less desirable than this:
var myShinyNewObject = new myInjectedFactory();
(But you should be wary about using this type of pattern in the first place because new-ing objects in your controllers creates hard-to-track dependencies that are difficult to mock for testing. Better to have a service manage a collection of objects for you than use new()
wily-nilly.)
One more thing, they are all Singletons...
Also keep in mind that in both cases, angular is helping you manage a singleton. Regardless of where or how many times you inject your service or function, you will get the same reference to the same object or function. (With the exception of when a factory simply returns a value like a number or string. In that case, you will always get the same value, but not a reference.)
简单的说 ..
// Service
service = (a, b) => {
a.lastName = b;
return a;
};
// Factory
factory = (a, b) => Object.assign({}, a, { lastName: b });
const fullName = { firstName: 'john' };
// Service
const lastNameService = (a, b) => {
a.lastName = b;
return a;
};
console.log(lastNameService(fullName, 'doe'));
// Factory
const lastNameFactory = (a, b) =>
Object.assign({}, a, { lastName: b })
console.log(lastNameFactory(fullName, 'doe'));
Here are the primary differences:
Services
Syntax: module.service( 'serviceName', function );
Result: When declaring serviceName as an injectable argument you will be provided with the instance of a function passed to module.service
.
Usage: Could be useful for sharing utility functions that are useful to invoke by simply appending ( )
to the injected function reference. Could also be run with injectedArg.call( this )
or similar.
Factories
Syntax: module.factory( 'factoryName', function );
Result: When declaring factoryName as an injectable argument you will be provided with the value that is returned by invoking the function reference passed to module.factory
.
Usage: Could be useful for returning a 'class' function that can then be new'ed to create instances.
Here is example using services and factory. Read more about AngularJS Service vs Factory.
You can also check the AngularJS documentation and similar question on stackoverflow confused about service vs factory.
链接地址: http://www.djcxy.com/p/2186.html