AngularJS中的服务、提供商和工厂之间有什么区别?
当前回答
我知道很多很好的答案,但我必须分享我的使用经验1.大多数违约情况下的服务2.用于创建特定实例的服务的工厂
// factory.js ////////////////////////////
(function() {
'use strict';
angular
.module('myApp.services')
.factory('xFactory', xFactoryImp);
xFactoryImp.$inject = ['$http'];
function xFactoryImp($http) {
var fac = function (params) {
this._params = params; // used for query params
};
fac.prototype.nextPage = function () {
var url = "/_prc";
$http.get(url, {params: this._params}).success(function(data){ ...
}
return fac;
}
})();
// service.js //////////////////////////
(function() {
'use strict';
angular
.module('myApp.services')
.service('xService', xServiceImp);
xServiceImp.$inject = ['$http'];
function xServiceImp($http) {
this._params = {'model': 'account','mode': 'list'};
this.nextPage = function () {
var url = "/_prc";
$http.get(url, {params: this._params}).success(function(data){ ...
}
}
})();
并使用:
controller: ['xFactory', 'xService', function(xFactory, xService){
// books = new instance of xFactory for query 'book' model
var books = new xFactory({'model': 'book', 'mode': 'list'});
// accounts = new instance of xFactory for query 'accounts' model
var accounts = new xFactory({'model': 'account', 'mode': 'list'});
// accounts2 = accounts variable
var accounts2 = xService;
...
其他回答
为了澄清这一点,从AngularJS源代码中,您可以看到一个服务只是调用工厂函数,而工厂函数反过来调用提供程序函数:
function factory(name, factoryFn) {
return provider(name, { $get: factoryFn });
}
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
从AngularJS邮件列表中,我得到了一个令人惊叹的线程,它解释了服务与工厂与供应商以及它们的注入用法。编写答案:
服务
语法:module.service('serviceName',function);结果:当将serviceName声明为可注入参数时,将为您提供函数的实例。换句话说,新的FunctionYouPassedToService()。
工厂
语法:module.factory('factoryName',function);结果:当将factoryName声明为可注入参数时,将提供通过调用传递给module.factory的函数引用返回的值。
提供商
语法:module.provider('providerName',function);结果:当将providerName声明为可注入参数时,将提供(newProviderFunction())$get()。在调用$get方法之前实例化构造函数函数-ProviderFunction是传递给module.provider的函数引用。
提供程序的优点是可以在模块配置阶段进行配置。
请参阅此处获取提供的代码。
下面是Misko的进一步解释:
provide.value('a', 123);
function Controller(a) {
expect(a).toEqual(123);
}
在这种情况下,注入器只是按原样返回值。但是如果您想计算该值呢?然后使用工厂
provide.factory('b', function(a) {
return a*2;
});
function Controller(b) {
expect(b).toEqual(246);
}
因此,工厂是一个负责创造价值的职能部门。注意,工厂函数可以要求其他依赖项。
但是,如果你想成为更多的OO,并拥有一个名为Greeter的类呢?
function Greeter(a) {
this.greet = function() {
return 'Hello ' + a;
}
}
然后,要实例化,必须编写
provide.factory('greeter', function(a) {
return new Greeter(a);
});
然后我们可以像这样在控制器中请求“问候者”
function Controller(greeter) {
expect(greeter instanceof Greeter).toBe(true);
expect(greeter.greet()).toEqual('Hello 123');
}
但这太啰嗦了。一个简短的写法是provider.service(“greeter”,greeter);
但是如果我们想在注入之前配置Greeter类呢?然后我们可以写
provide.provider('greeter2', function() {
var salutation = 'Hello';
this.setSalutation = function(s) {
salutation = s;
}
function Greeter(a) {
this.greet = function() {
return salutation + ' ' + a;
}
}
this.$get = function(a) {
return new Greeter(a);
};
});
然后我们可以这样做:
angular.module('abc', []).config(function(greeter2Provider) {
greeter2Provider.setSalutation('Halo');
});
function Controller(greeter2) {
expect(greeter2.greet()).toEqual('Halo 123');
}
顺便说一句,服务、工厂和价值都来自提供者。
provider.service = function(name, Class) {
provider.provide(name, function() {
this.$get = function($injector) {
return $injector.instantiate(Class);
};
});
}
provider.factory = function(name, factory) {
provider.provide(name, function() {
this.$get = function($injector) {
return $injector.invoke(factory);
};
});
}
provider.value = function(name, value) {
provider.factory(name, function() {
return value;
});
};
对我来说,理解差异的最佳和最简单的方法是:
var service, factory;
service = factory = function(injection) {}
AngularJS如何实例化特定组件(简化):
// service
var angularService = new service(injection);
// factory
var angularFactory = factory(injection);
因此,对于服务,AngularJS组件是由服务声明函数表示的类的对象实例。对于工厂,它是从工厂声明函数返回的结果。工厂的行为可能与服务相同:
var factoryAsService = function(injection) {
return new function(injection) {
// Service content
}
}
最简单的思考方式如下:
服务是一个单例对象实例。如果您想为代码提供单例对象,请使用服务。工厂是一个阶级。如果您想为代码提供自定义类,请使用工厂(无法使用服务完成,因为它们已经实例化)。
工厂“类”示例在周围的注释中提供,以及提供程序差异。
正如这里的几个人正确指出的,工厂、供应商、服务,甚至价值和常量都是同一事物的版本。您可以将更通用的提供程序分解为所有这些提供程序。像这样:
这是本文的图片来源:
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
对我来说,当我意识到它们都以相同的方式工作时,我就发现了这一点:通过运行一次某个东西,存储它们获得的值,然后在通过依赖注入引用时提取相同的存储值。
假设我们有:
app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);
三者之间的区别在于:
a的存储值来自运行fn。b的存储值来自newing fn。c的存储值来自首先通过newing fn获取一个实例,然后运行该实例的$get方法。
这意味着在AngularJS中有一个类似于缓存对象的东西,每次注入的值仅在第一次注入时分配一次,其中:
cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()
这就是为什么我们在服务中使用这个,并定义一个This$获取提供者。
推荐文章
- 在AngularJS中集成jQuery插件的正确方法
- 如何设置一个iframe src属性从一个变量在AngularJS
- 如何在Angular中使用$rootScope来存储变量?
- AngularJS:工厂和服务?
- 父ng-repeat从子ng-repeat的访问索引
- 无法解析类型为“Microsoft.AspNetCore.Http.IHttpContextAccessor”的服务
- AngularJS使用ng-class切换类
- 如何在Angular.js中配置不同的环境?
- 当使用ng-model时,输入文本框上的Value属性被忽略?
- 使用AngularJS跟踪谷歌分析页面视图
- 传递参数
- 在“DOMWindow”上执行“postMessage”失败:https://www.youtube.com !== http://localhost:9000
- Angular中相当于AngularJS $watch的东西是什么?
- AngularJS路由不带散列“#”
- 单击表单中的按钮会刷新页面