我已经看到angular.factory()和angular.service()被用来声明服务;然而,我找不到角。在官方文件的任何地方提供服务。
这两种方法有什么区别? 哪个应该用来做什么(假设它们做不同的事情)?
我已经看到angular.factory()和angular.service()被用来声明服务;然而,我找不到角。在官方文件的任何地方提供服务。
这两种方法有什么区别? 哪个应该用来做什么(假设它们做不同的事情)?
当前回答
App.factory ('fn',fn) vs. app.service('fn',fn)
建设
对于工厂,Angular将调用该函数来获得结果。它是被缓存和注入的结果。
//factory
var obj = fn();
return obj;
对于服务,Angular会通过调用new来调用构造函数。构造的函数被缓存和注入。
//service
var obj = new fn();
return obj;
实现
工厂通常返回一个对象文字,因为返回值是注入到控制器、运行块、指令等中的值
app.factory('fn', function(){
var foo = 0;
var bar = 0;
function setFoo(val) {
foo = val;
}
function setBar (val){
bar = val;
}
return {
setFoo: setFoo,
serBar: setBar
}
});
服务函数通常不返回任何东西。相反,它们执行初始化和公开函数。函数也可以引用“this”,因为它是用“new”构造的。
app.service('fn', function () {
var foo = 0;
var bar = 0;
this.setFoo = function (val) {
foo = val;
}
this.setBar = function (val){
bar = val;
}
});
结论
当涉及到使用工厂或服务时,它们都非常相似。它们被注入到控制器、指令、运行块等中,并以几乎相同的方式用于客户端代码。它们都是单例的——这意味着同一个实例在注入服务/工厂的所有地方共享。
那么你更喜欢哪一种呢?不管是哪一种,它们都非常相似,差异微不足道。如果您选择其中一个而不是另一个,请注意它们是如何构造的,以便您可以正确地实现它们。
其他回答
以下是主要的区别:
服务
语法:模块。service('serviceName',函数);
结果:当将serviceName声明为可注入参数时,你将得到传递给module.service的函数实例。
使用方法:可以通过简单地将()附加到注入的函数引用来共享有用的实用程序函数。也可以用injectedArg运行。调用(这个)或类似的方法。
工厂
语法:模块。factory('factoryName',函数);
结果:当将factoryName声明为一个可注入参数时,将为您提供通过调用传递给module.factory的函数引用返回的值。
用法:可能用于返回一个'class'函数,然后可以重新创建实例。
下面是使用服务和工厂的示例。阅读更多关于AngularJS服务vs工厂的文章。
你也可以查看AngularJS的文档和类似的关于stackoverflow混淆服务和工厂的问题。
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都是在帮助你管理单例对象。无论注入服务或函数的位置或次数如何,都将获得对相同对象或函数的相同引用。(当工厂只是返回一个像数字或字符串的值时除外。在这种情况下,你将总是得到相同的值,但不是引用。)
线索就在名字里
服务和工厂彼此相似。两者都将产生一个可以注入到其他对象中的单例对象,因此通常可以互换使用。
它们旨在从语义上用于实现不同的设计模式。
服务用于实现服务模式
服务模式是将应用程序分解为逻辑一致的功能单元的模式。例如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!";
}
}
});
简单地说…
Const user = { 名字:“约翰” }; / /工厂 const addLastNameFactory = (user, lastName) => ({ 用户, 姓, }); console.log (addLastNameFactory(用户、“母鹿”)); / /服务 const addLastNameService = (user, lastName) => { 用户。lastName = lastName;/ /坏!突变 返回用户; }; console.log (addLastNameService(用户、“母鹿”));
App.factory ('fn',fn) vs. app.service('fn',fn)
建设
对于工厂,Angular将调用该函数来获得结果。它是被缓存和注入的结果。
//factory
var obj = fn();
return obj;
对于服务,Angular会通过调用new来调用构造函数。构造的函数被缓存和注入。
//service
var obj = new fn();
return obj;
实现
工厂通常返回一个对象文字,因为返回值是注入到控制器、运行块、指令等中的值
app.factory('fn', function(){
var foo = 0;
var bar = 0;
function setFoo(val) {
foo = val;
}
function setBar (val){
bar = val;
}
return {
setFoo: setFoo,
serBar: setBar
}
});
服务函数通常不返回任何东西。相反,它们执行初始化和公开函数。函数也可以引用“this”,因为它是用“new”构造的。
app.service('fn', function () {
var foo = 0;
var bar = 0;
this.setFoo = function (val) {
foo = val;
}
this.setBar = function (val){
bar = val;
}
});
结论
当涉及到使用工厂或服务时,它们都非常相似。它们被注入到控制器、指令、运行块等中,并以几乎相同的方式用于客户端代码。它们都是单例的——这意味着同一个实例在注入服务/工厂的所有地方共享。
那么你更喜欢哪一种呢?不管是哪一种,它们都非常相似,差异微不足道。如果您选择其中一个而不是另一个,请注意它们是如何构造的,以便您可以正确地实现它们。