我知道这个问题已被提出并已给出答案。但是我通过实际例子学到了最好的知识,而且我遇到了一些我并不完全理解的代码。
我指的是Angular Strap,这是一组很酷的用户交互指令: http://mgcrea.github.io/angular-strap/
我正在查看工具提示功能的代码,并看到作者正在使用提供程序来公开功能。他也可以用服务或工厂做同样的工作吗?或者是必要的提供者?
以下是代码的链接:https://github.com/mgcrea/angular-strap/blob/master/src/tooltip/tooltip.js#L28
谢谢
答案 0 :(得分:4)
虽然文档是正确的,但每种情况都有特殊情况我认为回答它们都是一样的也很重要。
factory
是provider
的专用版本,在某些情况下,您可以使用更少的代码完成相同的操作。反过来,service
和value
是factory
的特例。 constant
是value
的特例。
这是一张图片,一目了然地显示了我的意思:
您可以在图片所在的博客上获取更多详细信息:http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
还有另一个关于Stack Overflow的问题,其中包含类似的详细信息: https://stackoverflow.com/a/33805462/984780
答案 1 :(得分:2)
有五种食谱类型。
最详细,但也是最全面的是提供者食谱。剩下的四种食谱类型 - 价值,工厂,服务和常数 - 只是提供者食谱之上的语法糖。
因此,实质上,构建服务和构建提供商是完全相同的,假设您不需要访问某些高级设置。他们继续说:
只有当您希望公开应用程序范围内必须在应用程序启动之前进行的配置的API时,才应使用提供程序配方。
这是一张表:
功能/配方类型
Factory Service Value Constant Provider can have dependencies yes yes no no yes uses type friendly injection no yes yes* yes* no object available in config phase no no no yes yes** can create functions yes yes yes yes yes can create primitives yes no yes yes yes*以直接使用new运算符的急切初始化为代价
**服务对象在配置阶段不可用,但提供者实例是。
答案 2 :(得分:1)
Angular为我们提供了三种创建和注册自己的方法 服务。
厂
服务
提供商
<强> 1。工厂:当您使用工厂时,您创建一个对象,向其添加属性,然后返回该对象。当您将此服务传递到控制器时,该对象上的这些属性现在将通过您的工厂在该控制器中可用。
示例:
app.controller('myFactoryCtrl', function ($scope, myFactory) {
$scope.artist = myFactory.getArtist()
});
app.factory('myFactory', function () {
var _artist = '';
var service = {}
service.getArtist = function () {
return _artist
}
return service;
});
2服务:当您使用服务时,它会使用'new'关键字进行实例化。因此,您将向'this'添加属性,服务将返回'this'。当您将服务传递到控制器时,“this”上的这些属性现在可以通过您的服务在该控制器上使用。
示例:
app.controller('myServiceCtrl', function ($scope, myService) {
$scope.artist = myService.getArtist();
});
app.service('myService', function () {
var _artist = '';
this.getArtist = function () {
return _artist;
}
});
3提供商:提供商是您可以传递到.config()函数的唯一服务。如果要在服务对象可用之前为其提供模块范围的配置,请使用提供程序。
示例:
app.controller('myProviderCtrl', function ($scope, myProvider) {
$scope.artist = myProvider.getArtist();
$scope.data.thingFromConfig = myProvider.thingOnConfig;
});
app.provider('myProvider', function () {
this._artist = '';
this.thingFromConfig = '';
//Only the properties on the object returned from $get are available in the controller.
this.$get = function () {
var that = this;
return {
getArtist: function () {
return that._artist;
},
thingonConfig: that.thingFromConfig
}
}
});
app.config(function (myProviderProvider) {
myProviderProvider.thingFromConfig = 'This was set in config()';
});
详细了解服务click here
答案 3 :(得分:0)
简短回答:作者选择“提供商”使默认设置为“只读”。如果没有使用提供商,代码仍然有用,但提供商更清洁,更安全
Provider
,Service
和Factory
在Angular中都是相同的基本内容,只是使用不同的API; Provider
可以将有点视为“基础”元素,但它们都具有相同的最终目的:创建一个Angular注入。这些注入中的每一个都有一个提供蓝图的提供者(Angular查找$get
方法),以及提供者生成的Singleton实例。如果您使用Factory
或Service
,Angular会在幕后工作,因此您无需了解所有细节;你只会有一个非常无聊的Provider
只能做基础知识。但是,如果您自己使用Provider
,则可以在声明中添加额外的属性和函数。
您可以将Providers
注入模块的config()
方法,该方法在创建任何单例之前运行。请尝试查看here以获得更长的解释。
在AngularStrap中,作者在提供者上放置了“默认”对象。作者希望您在模块的config()
方法中修改该对象,然后Angular将生成Singleton。但是,“默认值”对象在单身人士上不,因此一旦应用“正在运行”,您就无法更改默认值。即使您再次在某处注入Provider
并再次更改'default',Angular也不会重新生成您的Singleton,因此默认值有效地变为'只读'。这是一种很好的做法,可以防止代码进行不必要的更改,尤其是当您在同一代码中有多个人,或者您知道其他人将使用您的模块时。
您可能会看到其他代码无法正常工作......也许其他应用只使用factory
,并将“默认”对象放在该工厂上。它仍然可以“正常工作”,代码看起来很像现在。但是,因为“默认值”将直接在Singleton上,您的代码可能会在任何时候更改这些设置如果有人编写代码来执行此操作。现在您必须留下评论和文档,说明何时更改默认值,何时不更改默认值等等;对于99%的案例,一旦应用程序运行,默认值就不需要更改,因此使用Provider
和module.config()
是安全和直接的。