我已经看到angular.factory()和angular.service()用于声明服务; 但是,我在官方文档中找不到 angular.service
。
这两种方法有什么区别?应该用什么(假设他们做不同的事情)?
angular.service('myService', myServiceFunction);
angular.factory('myFactory', myFactoryFunction);
我无法绕过这个概念,直到我这样说:
服务 :你编写的函数将是新的 :
myInjectedService <---- new myServiceFunction()
Factory :将调用您编写的函数 (构造函数):
myInjectedFactory <--- myFactoryFunction()
你用它做什么取决于你,但有一些有用的模式......
function myServiceFunction() {
this.awesomeApi = function(optional) {
// calculate some stuff
return awesomeListOfValues;
}
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.awesome = myInjectedService.awesomeApi();
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();
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();
你可以用两者完成同样的事情。但是,在某些情况下, 工厂可以更灵活地创建具有更简单语法的注入。这是因为 myInjectedService 必须始终是一个对象,myInjectedFactory 可以是一个对象,一个函数引用或任何值。例如,如果您编写了一个服务来创建构造函数(如上面的上一个示例所示),则必须实例化它:
var myShinyNewObject = new myInjectedService.myFunction()
这可能比这更不可取:
var myShinyNewObject = new myInjectedFactory();
(但是你应该首先考虑使用这种类型的模式,因为控制器中的新对象会创建难以模拟测试的难以跟踪的依赖关系。更好地让服务管理对象的集合你比使用new()
狡猾的。)
还要记住,在这两种情况下,angular 都可以帮助您管理单身人士。无论您注入服务或功能的位置或次数,您都将获得对同一对象或功能的相同引用。 (除了工厂只返回一个数字或字符串之类的值。在这种情况下,您将始终获得相同的值,但不是引用。)
简单的说 ..
// 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'));
以下是主要差异:
语法: module.service( 'serviceName', function );
结果:将 serviceName 声明为 injectable 参数时,将向您提供传递给module.service
的函数的实例 。
用法:通过简单地向注入的函数引用附加( )
来共享对调用有用的实用程序函数非常有用。也可以使用injectedArg.call( this )
或类似的方式运行。
语法: module.factory( 'factoryName', function );
结果:当将 factoryName 声明为 injectable 参数时,将通过调用传递给module.factory
的函数引用来提供返回的值 。
用法:用于返回一个'class'函数,然后可以用来创建实例。
这是使用服务和工厂的示例 。阅读更多关于AngularJS Service vs Factory 的信息 。
您还可以检查AngularJS 文档以及有关服务与工厂混淆的 stackoverflow 上的类似问题。