AngularJS中的服务、提供商和工厂之间有什么区别?
当前回答
JS Fiddle演示
工厂/服务/供应商的“Hello world”示例:
var myApp=角度模块('myApp',[]);//服务风格,可能是最简单的myApp.service('helloWorldFromService',函数(){this.sayHello=函数(){return“你好,世界!”;};});//工厂风格,更加复杂myApp.factory('helloWorldFromFactory',函数(){返回{sayHello:函数(){return“你好,世界!”;}};});//提供程序风格、全面、可配置版本myApp.provider('helloWorld',函数(){this.name='默认值';这一点$get=函数(){var名称=this.name;返回{sayHello:函数(){return“您好,”+name+“!”;}}};this.setName=函数(名称){this.name=名称;};});//嘿,我们可以配置提供者!myApp.config(函数(helloWorldProvider){helloWorldProvider.setName('World');});函数MyCtrl($scope、helloWorld、helloWorldFromFactory、helloWorldFromService){$scope.hellos=[helloWorld.sayHello(),helloWorldFromFactory.sayHello(),helloWorldFromService.sayHello()];}<script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js“></script><body ng app=“myApp”><div ng controller=“MyCtrl”>{{hellos}}</div></body>
其他回答
句法糖是区别。只需要提供程序。或者换句话说,只有提供者才是真正的角度,所有其他提供者都是派生的(以减少代码)。还有一个简单的版本,叫做Value(),它只返回值,不返回计算或函数。偶数值是从提供程序派生的!
那么,为什么会出现这样的并发症,为什么我们不能只使用提供者而忘记其他一切呢?它应该可以帮助我们轻松编写代码,更好地进行沟通。开玩笑的回答是,它越复杂,框架的销售就越好。
可以返回value=value的提供程序一个可以实例化并返回=工厂(+值)提供程序可以实例化+做某事=服务(+工厂,+值)提供者=必须包含名为$get(+Factory,+Service,+Value)的属性
角注入为我们得出这一结论提供了第一个线索。
$injector用于检索提供者“不是服务,不是工厂,而是提供者”定义的对象实例。
更好的答案是:Angular服务由服务工厂创建。这些服务工厂是由服务提供程序创建的函数。服务提供程序是构造函数。实例化时,它们必须包含名为$get的属性,该属性保存服务工厂函数
因此,主供应器和注入器都将就位:)。当$get可以通过从IServiceProvider继承而在提供程序中实现时,Typescript就变得有趣了。
让我们以简单的方式讨论AngularJS中处理业务逻辑的三种方法:(灵感来自Yaakov的Coursera AngularJS课程)
服务:
语法:
应用程序.js
var app = angular.module('ServiceExample',[]);
var serviceExampleController =
app.controller('ServiceExampleController', ServiceExampleController);
var serviceExample = app.service('NameOfTheService', NameOfTheService);
ServiceExampleController.$inject = ['NameOfTheService'] //protects from minification of js files
function ServiceExampleController(NameOfTheService){
serviceExampleController = this;
serviceExampleController.data = NameOfTheService.getSomeData();
}
function NameOfTheService(){
nameOfTheService = this;
nameOfTheService.data = "Some Data";
nameOfTheService.getSomeData = function(){
return nameOfTheService.data;
}
}
索引html
<div ng-controller = "ServiceExampleController as serviceExample">
{{serviceExample.data}}
</div>
服务特点:
懒惰实例化:如果它没有被注入,就永远不会被实例化。因此,要使用它,必须将其注入到模块中。Singleton:如果注入到多个模块,所有模块都只能访问一个特定的实例。这就是为什么在不同控制器之间共享数据非常方便的原因。
工厂
首先让我们看看语法:
应用.js:
var app = angular.module('FactoryExample',[]);
var factoryController = app.controller('FactoryController', FactoryController);
var factoryExampleOne = app.factory('NameOfTheFactoryOne', NameOfTheFactoryOne);
var factoryExampleTwo = app.factory('NameOfTheFactoryTwo', NameOfTheFactoryTwo);
//first implementation where it returns a function
function NameOfTheFactoryOne(){
var factory = function(){
return new SomeService();
}
return factory;
}
//second implementation where an object literal would be returned
function NameOfTheFactoryTwo(){
var factory = {
getSomeService : function(){
return new SomeService();
}
};
return factory;
}
现在在控制器中使用以上两个:
var factoryOne = NameOfTheFactoryOne() //since it returns a function
factoryOne.someMethod();
var factoryTwo = NameOfTheFactoryTwo.getSomeService(); //accessing the object
factoryTwo.someMethod();
工厂特点:
遵循工厂设计模式。工厂是生产新对象或功能的中心场所。不仅生成单例,还生成可定制的服务。.service()方法是一个工厂,它总是生成相同类型的服务,这是一个单例,没有任何简单的方法来配置它的行为。.service()方法通常用作不需要任何配置的快捷方式。
供应商
让我们先来看看语法:
angular.module('ProviderModule', [])
.controller('ProviderModuleController', ProviderModuleController)
.provider('ServiceProvider', ServiceProvider)
.config(Config); //optional
Config.$inject = ['ServiceProvider'];
function Config(ServiceProvider) {
ServiceProvider.defaults.maxItems = 10; //some default value
}
ProviderModuleController.$inject = ['ServiceProvider'];
function ProviderModuleController(ServiceProvider) {
//some methods
}
function ServiceProvider() {
var provider = this;
provider.defaults = {
maxItems: 10
};
provider.$get = function () {
var someList = new someListService(provider.defaults.maxItems);
return someList;
};
}
}
提供商的特点:
Provider是在Angular中创建服务的最灵活的方法。我们不仅可以创建一个可动态配置的工厂,而且在使用工厂时,通过提供程序方法,我们可以在整个应用程序启动时自定义配置工厂一次。然后,工厂可以在整个应用程序中使用自定义设置。换句话说,我们可以在应用程序启动之前配置此工厂。事实上,在angular文档中提到,当我们使用.service或.factory方法配置服务时,提供者方法实际上是在幕后执行的。$get是一个直接附加到提供程序实例的函数。该函数是工厂函数。换句话说,它就像我们用来提供给.factory方法的一样。在该函数中,我们创建自己的服务。这个$get属性是一个函数,它使提供者成为提供者。AngularJS希望提供程序具有$get属性,该属性的值是Angular将作为工厂函数处理的函数。但使整个提供程序设置非常特殊的是,我们可以在服务提供程序内部提供一些配置对象,这通常带有默认值,我们可以稍后在步骤中覆盖这些默认值,在该步骤中我们可以配置整个应用程序。
工厂:您实际在工厂内部创建对象并将其返回的工厂。service:您只有一个使用this关键字定义函数的标准函数的服务。provider:您定义了一个$get,它可以用来获取返回数据的对象。
对我来说,理解差异的最佳和最简单的方法是:
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
}
}
最简单的思考方式如下:
服务是一个单例对象实例。如果您想为代码提供单例对象,请使用服务。工厂是一个阶级。如果您想为代码提供自定义类,请使用工厂(无法使用服务完成,因为它们已经实例化)。
工厂“类”示例在周围的注释中提供,以及提供程序差异。
此答案针对主题/问题
Factory、Service和Constant是如何在提供者配方之上添加语法糖的?
OR
工厂、服务和供应商在内部是怎样的
基本上发生的是
当您创建factory()时,它会将第二个参数中提供的函数设置为provider的$get并返回它(provider(name,{$get:factoryFn})),您所得到的只是provider,但除了$get之外没有其他属性/方法(这意味着您无法配置)
工厂源代码
function factory(name, factoryFn, enforce) {
return provider(name, {
$get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
});
};
当生成服务()时,它返回您提供factory()的函数,该函数注入构造函数(返回您在服务中提供的构造函数的实例)并返回它
服务源代码
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
};
因此,基本上在这两种情况下,您最终都会将providers$get设置为您提供的函数,但您可以提供$get以外的任何内容,因为您最初可以在provider()中为config块提供
推荐文章
- AngularJS控制器的生命周期是什么?
- $destroy是否删除事件监听器?
- 用布尔值将单选按钮绑定到模型
- AngularJS只适用于单页应用程序吗?
- angular.js中的内联条件
- 如何突出显示当前菜单项?
- 如何使用AngularJS获取url参数
- angularjs中的compile函数和link函数有什么区别
- 如何向一个5岁的孩子解释依赖注入?
- Ng-repeat结束事件
- 缓存一个HTTP 'Get'服务响应在AngularJS?
- 从ng-click获取原始元素
- Angular JS:当我们已经有了具有作用域的指令控制器时,指令的link函数还需要什么?
- Angularjs的ng-model不能在ng-if中工作
- AngularJS禁用了开发机器上的部分缓存