Angular JS 工厂 vs 服务 vs 提供者的例子
Angular JS factory vs service vs provider by example
我知道这个问题已经被提出并且已经给出了答案。但是我通过实际示例学得最好,并且遇到了我不完全理解的代码。
我指的是 Angular Strap,它是一组很棒的用户交互指令:
http://mgcrea.github.io/angular-strap/
我正在查看工具提示功能的代码,发现作者正在使用提供程序来公开功能。他是否也可以使用服务或工厂来完成同样的工作?或者是否需要提供者?
这是代码的 link:https://github.com/mgcrea/angular-strap/blob/master/src/tooltip/tooltip.js#L28
谢谢
简答:作者选择了 Provider 作为默认设置 'read-only'。如果他们没有 使用 Provider,代码仍然可以工作,但 Provider 更干净并且 'safer'
Provider
、Service
、Factory
在Angular中都是一样的基本东西,只是API不同而已; Provider
可以 kinda 被认为是 'base' 元素,但它们都有相同的最终目的:创建一个 Angular 可注入。这些可注射物中的每一个都有一个提供蓝图的提供者(Angular 寻找 $get
方法),以及提供者生成的单例实例。如果您使用 Factory
或 Service
,Angular 确实在幕后工作,因此您无需了解所有细节;您将只有一个非常无聊的 Provider
,它只做基础工作。但是,如果您自己使用 Provider
,则可以在声明中为其添加额外的属性和函数。
您可以将 Providers
注入模块的 config()
方法,即 运行 在创建任何单例之前。尝试查看 here 以获得更详细的解释。
在AngularStrap中,作者在Provider上放置了一个'defaults'对象。作者希望您在模块的 config()
方法中修改该对象,然后 Angular 将生成 Singleton。但是,'defaults' 对象在单例 上不是,因此您不能更改默认值 一旦应用程序是 'running'。即使你在某处再次注入 Provider
并再次更改“默认值”,Angular 也不会重新创建你的单例,因此默认值实际上变成了 'read-only'。这是防止代码进行不需要的更改的好做法,尤其是当您有多个人在同一代码中,或者您知道其他人将使用您的模块时。
您可能会看到其他代码无法像那样工作...也许另一个应用程序只是使用 factory
,并将 'defaults' 对象放在该工厂上。它仍然是 'work',并且代码看起来很像当前的样子。然而,因为 'defaults' 将直接在 Singleton 上,你的代码可以在任何时候更改这些设置 如果有人编写代码来这样做。现在您必须留下注释和文档来解释何时更改默认值,何时不更改默认值,等等;对于 99% 的情况,一旦应用 运行ning,默认值永远不需要更改,因此使用 Provider
和 module.config()
是安全和直接的。
There are five recipe types.
The most verbose, but also the most comprehensive one is a Provider recipe. The remaining four recipe types — Value, Factory, Service and Constant — are just syntactic sugar on top of a provider recipe.
因此,从本质上讲,构建服务和构建提供者是相同的,前提是您不需要访问某些高级设置。他们接着说:
You should use the Provider recipe only when you want to expose an API for application-wide configuration that must be made before the application starts.
这里是 table:
Features / Recipe type
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
* at the cost of eager initialization by using new operator directly
** the service object is not available during the config phase, but the provider instance is.
虽然文档是正确的,每个都有特殊情况可以使用,但我认为回答它们都是同一件事也很重要。
factory
是 provider
的一个特殊版本,在某些情况下,它可以让您使用更少的代码完成同样的事情。反过来 service
和 value
是 factory
的特例。而 constant
是 value
.
的特例
这张图片让你一目了然:
(来源:simplygoodcode.com)
您可以在图片来自的博客上获得更多详细信息:http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
关于 Stack Overflow 的另一个问题也有类似的细节:
Angular provides us with three ways to create and register our own
service.
工厂
服务
提供商
1. Factory : 当你使用 Factory 时,你创建一个对象,向它添加属性,然后 return 同一个对象。当您将此服务传递到您的控制器时,对象上的这些属性现在将通过您的工厂在该控制器中可用。
示例:
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 Service: 当你使用 Service 时,它是用‘new’关键字实例化的。因此,您将向“this”添加属性,服务将 return“this”。当您将服务传递到您的控制器时,“this”上的那些属性现在将通过您的服务在该控制器上可用。
示例:
app.controller('myServiceCtrl', function ($scope, myService) {
$scope.artist = myService.getArtist();
});
app.service('myService', function () {
var _artist = '';
this.getArtist = function () {
return _artist;
}
});
3 Provider : Providers 是唯一可以传递给 .config() 函数的服务。如果您想在服务对象可用之前为其提供 module-wide 配置,请使用提供程序。
示例:
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
我知道这个问题已经被提出并且已经给出了答案。但是我通过实际示例学得最好,并且遇到了我不完全理解的代码。
我指的是 Angular Strap,它是一组很棒的用户交互指令: http://mgcrea.github.io/angular-strap/
我正在查看工具提示功能的代码,发现作者正在使用提供程序来公开功能。他是否也可以使用服务或工厂来完成同样的工作?或者是否需要提供者?
这是代码的 link:https://github.com/mgcrea/angular-strap/blob/master/src/tooltip/tooltip.js#L28
谢谢
简答:作者选择了 Provider 作为默认设置 'read-only'。如果他们没有 使用 Provider,代码仍然可以工作,但 Provider 更干净并且 'safer'
Provider
、Service
、Factory
在Angular中都是一样的基本东西,只是API不同而已; Provider
可以 kinda 被认为是 'base' 元素,但它们都有相同的最终目的:创建一个 Angular 可注入。这些可注射物中的每一个都有一个提供蓝图的提供者(Angular 寻找 $get
方法),以及提供者生成的单例实例。如果您使用 Factory
或 Service
,Angular 确实在幕后工作,因此您无需了解所有细节;您将只有一个非常无聊的 Provider
,它只做基础工作。但是,如果您自己使用 Provider
,则可以在声明中为其添加额外的属性和函数。
您可以将 Providers
注入模块的 config()
方法,即 运行 在创建任何单例之前。尝试查看 here 以获得更详细的解释。
在AngularStrap中,作者在Provider上放置了一个'defaults'对象。作者希望您在模块的 config()
方法中修改该对象,然后 Angular 将生成 Singleton。但是,'defaults' 对象在单例 上不是,因此您不能更改默认值 一旦应用程序是 'running'。即使你在某处再次注入 Provider
并再次更改“默认值”,Angular 也不会重新创建你的单例,因此默认值实际上变成了 'read-only'。这是防止代码进行不需要的更改的好做法,尤其是当您有多个人在同一代码中,或者您知道其他人将使用您的模块时。
您可能会看到其他代码无法像那样工作...也许另一个应用程序只是使用 factory
,并将 'defaults' 对象放在该工厂上。它仍然是 'work',并且代码看起来很像当前的样子。然而,因为 'defaults' 将直接在 Singleton 上,你的代码可以在任何时候更改这些设置 如果有人编写代码来这样做。现在您必须留下注释和文档来解释何时更改默认值,何时不更改默认值,等等;对于 99% 的情况,一旦应用 运行ning,默认值永远不需要更改,因此使用 Provider
和 module.config()
是安全和直接的。
There are five recipe types.
The most verbose, but also the most comprehensive one is a Provider recipe. The remaining four recipe types — Value, Factory, Service and Constant — are just syntactic sugar on top of a provider recipe.
因此,从本质上讲,构建服务和构建提供者是相同的,前提是您不需要访问某些高级设置。他们接着说:
You should use the Provider recipe only when you want to expose an API for application-wide configuration that must be made before the application starts.
这里是 table:
Features / Recipe type
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* at the cost of eager initialization by using new operator directly
** the service object is not available during the config phase, but the provider instance is.
虽然文档是正确的,每个都有特殊情况可以使用,但我认为回答它们都是同一件事也很重要。
factory
是 provider
的一个特殊版本,在某些情况下,它可以让您使用更少的代码完成同样的事情。反过来 service
和 value
是 factory
的特例。而 constant
是 value
.
这张图片让你一目了然:
(来源:simplygoodcode.com)
您可以在图片来自的博客上获得更多详细信息:http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
关于 Stack Overflow 的另一个问题也有类似的细节:
Angular provides us with three ways to create and register our own service.
工厂
服务
提供商
1. Factory : 当你使用 Factory 时,你创建一个对象,向它添加属性,然后 return 同一个对象。当您将此服务传递到您的控制器时,对象上的这些属性现在将通过您的工厂在该控制器中可用。
示例:
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 Service: 当你使用 Service 时,它是用‘new’关键字实例化的。因此,您将向“this”添加属性,服务将 return“this”。当您将服务传递到您的控制器时,“this”上的那些属性现在将通过您的服务在该控制器上可用。
示例:
app.controller('myServiceCtrl', function ($scope, myService) {
$scope.artist = myService.getArtist();
});
app.service('myService', function () {
var _artist = '';
this.getArtist = function () {
return _artist;
}
});
3 Provider : Providers 是唯一可以传递给 .config() 函数的服务。如果您想在服务对象可用之前为其提供 module-wide 配置,请使用提供程序。
示例:
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