我已经看到angular.factory()和angular.service()被用来声明服务;然而,我找不到角。在官方文件的任何地方提供服务。
这两种方法有什么区别? 哪个应该用来做什么(假设它们做不同的事情)?
我已经看到angular.factory()和angular.service()被用来声明服务;然而,我找不到角。在官方文件的任何地方提供服务。
这两种方法有什么区别? 哪个应该用来做什么(假设它们做不同的事情)?
当前回答
我花了一些时间试图弄清楚其中的区别。
我认为工厂函数使用模块模式,服务函数使用标准的java脚本构造函数模式。
其他回答
以下是主要的区别:
服务
语法:模块。service('serviceName',函数);
结果:当将serviceName声明为可注入参数时,你将得到传递给module.service的函数实例。
使用方法:可以通过简单地将()附加到注入的函数引用来共享有用的实用程序函数。也可以用injectedArg运行。调用(这个)或类似的方法。
工厂
语法:模块。factory('factoryName',函数);
结果:当将factoryName声明为一个可注入参数时,将为您提供通过调用传递给module.factory的函数引用返回的值。
用法:可能用于返回一个'class'函数,然后可以重新创建实例。
下面是使用服务和工厂的示例。阅读更多关于AngularJS服务vs工厂的文章。
你也可以查看AngularJS的文档和类似的关于stackoverflow混淆服务和工厂的问题。
简单地说…
Const user = { 名字:“约翰” }; / /工厂 const addLastNameFactory = (user, lastName) => ({ 用户, 姓, }); console.log (addLastNameFactory(用户、“母鹿”)); / /服务 const addLastNameService = (user, lastName) => { 用户。lastName = lastName;/ /坏!突变 返回用户; }; console.log (addLastNameService(用户、“母鹿”));
线索就在名字里
服务和工厂彼此相似。两者都将产生一个可以注入到其他对象中的单例对象,因此通常可以互换使用。
它们旨在从语义上用于实现不同的设计模式。
服务用于实现服务模式
服务模式是将应用程序分解为逻辑一致的功能单元的模式。例如API访问器或一组业务逻辑。
这在Angular中尤其重要,因为Angular模型通常只是从服务器上提取的JSON对象,所以我们需要一个地方来放置我们的业务逻辑。
这是一个Github服务的例子。它知道如何与Github对话。它知道url和方法。我们可以把它注入到控制器中,它会生成并返回一个承诺。
(function() {
var base = "https://api.github.com";
angular.module('github', [])
.service('githubService', function( $http ) {
this.getEvents: function() {
var url = [
base,
'/events',
'?callback=JSON_CALLBACK'
].join('');
return $http.jsonp(url);
}
});
)();
工厂实现工厂模式
另一方面,工厂旨在实现工厂模式。一种工厂模式,其中我们使用工厂函数来生成对象。通常我们会用它来建立模型。下面是一个返回Author构造函数的工厂:
angular.module('user', [])
.factory('User', function($resource) {
var url = 'http://simple-api.herokuapp.com/api/v1/authors/:id'
return $resource(url);
})
我们可以这样使用它:
angular.module('app', ['user'])
.controller('authorController', function($scope, User) {
$scope.user = new User();
})
注意,工厂也返回单例对象。
工厂可以返回构造函数
因为工厂只是返回一个对象,所以它可以返回任何类型的对象,包括构造函数,如上所述。
工厂返回一个对象;服务是可更新的
另一个技术差异在于服务和工厂的组合方式。一个新的服务函数将生成对象。工厂函数将被调用并返回该对象。
服务是可更新的构造函数。 工厂被简单地调用并返回一个对象。
这意味着在服务中,我们将“This”附加到构造函数的上下文中,它将指向正在构造的对象。
为了说明这一点,下面是使用服务和工厂创建的相同的简单对象:
angular.module('app', [])
.service('helloService', function() {
this.sayHello = function() {
return "Hello!";
}
})
.factory('helloFactory', function() {
return {
sayHello: function() {
return "Hello!";
}
}
});
我花了一些时间试图弄清楚其中的区别。
我认为工厂函数使用模块模式,服务函数使用标准的java脚本构造函数模式。
angular.service('myService', myServiceFunction);
angular.factory('myFactory', myFactoryFunction);
我很难理解这个概念,直到我这样对自己说:
Service:你所写的函数将被new-ed:
myInjectedService <---- new myServiceFunction()
Factory:你写的函数(构造函数)将被调用:
myInjectedFactory <--- myFactoryFunction()
你怎么做取决于你自己,但有一些有用的模式……
比如写一个服务函数来公开一个公共API:
function myServiceFunction() {
this.awesomeApi = function(optional) {
// calculate some stuff
return awesomeListOfValues;
}
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.awesome = myInjectedService.awesomeApi();
或者使用工厂函数公开一个公共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();
或者使用工厂函数返回构造函数:
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都是在帮助你管理单例对象。无论注入服务或函数的位置或次数如何,都将获得对相同对象或函数的相同引用。(当工厂只是返回一个像数字或字符串的值时除外。在这种情况下,你将总是得到相同的值,但不是引用。)