20 - AngularJS Service / Factory Tutorial with Example
http://viralpatel.net/blogs/angularjs-service-factory-tutorial/
In AngularJS you can make your own service, or use one of the many built-in services.
What is a Service?
In AngularJS, a service is a function, or object, that is available for, and limited to, your AngularJS application. AngularJS has about 30 built-in services. One of them is the $location service.
( Service nedir? Bir object'dir veya bir fonksiyondur. AngularJS'de tanımlı service'ler vardır, ancak kendimiz de yeni bir service tanımlayabiliriz. Bir controller'ın içinde bir service'i kullanabilmemiz için, önce bu controller'a kullanmak istediğimiz service'i inject etmeliyiz. Örneğin myCtrl isimli bir controller'a $location isimli bir service'i şöyle inject ederiz. Sonra bu controller'da $location service'i kullanabiliriz:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $location) {
$scope.myUrl = $location.absUrl(); }); )
The $location service has methods which return information about the location of the current web page($location isimli service current web sayfasının lokasyonu ile ilgili bilgileri return edern method'lara sahiptir.):
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<p>The url of this page is:</p>
<h3>{{myUrl}}</h3>
</div>
<p>This example uses the built-in $location service to get the absolute url of the page.</p>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $location) {
$scope.myUrl = $location.absUrl();
});
</script>
</body>
</html>
Note that the $location service is passed in to the controller as an argument. In order to use the service in the controller, it must be defined as a dependency (app.controller('myCtrl', function($scope, $location) diyerek myCtrl isimli controller'a $location isimli service'i inject ettik, yani bu controllar'ın location service'ine dependent(bağımlı) olduğunu söyledik.)
In AngularJS world, the services are singleton objects or functions that carry out specific tasks. It holds some business logic. Separation of concern is at the heart while designing an AngularJS application. Your controller must be responsible for binding model data to views using $scope. It does not contain logic to fetch the data or manipulating it. For that we must create singleton objects called services. AngularJS can manage these service objects. Wherever we want to use the service, we just have to specify its name and AngularJS auto-magically inject these objects (more on this later).
(AngularJS dünyasında, service'ler singleton object'lerdir, yani anonymous object'lerdir veya fonksiyonlardır. Herbir service belirli bir task'ı, belirli bir iş mantığını gerçekleştirir. Concern'leri birbirinden ayırmak, bir AngularJS uygulaması design etmenin kalbi gibidir, çok önemlidir. Controller'ımız $scope object'i kullanarak, model data'yı view'lere bind eder; controller veri fetch etmek veya manipulate etmek için kullanılmaz bu iş için service denilen singleton object'ler yaratırız. AngularJS bu service object'leri yönetebilir. Bir service object'i hangi controller'da kullanmak istiyorsak, önce bu service'i ilgili controller'a inject etmeliyiz. )
Thus service is a stateless object that contains some useful functions. These functions can be called from anywhere; Controllers, Directive, Filters etc. Thus we can divide our application in logical units. The business logic or logic to call HTTP url to fetch data from server can be put within a service object.
( Service object'ler fonksiyonlara sahiptirler, bu fonksiyonları herhangi bir yerden çağırabiliriz. Bu sayede uygulamamızı mantıksal birimlere bölebiliriz. Bir HTTP url'e request göndererek server'dan veri çekilmesi veya diğer business logic işlerini service object'ler içerisinde yapabiliriz. )
Putting business and other logic within services has many advantages. First it fulfills the principle of separation of concern or segregation of duties. Each component is responsible for its own work making application more manageable. Second this way each component can be more testable. AngularJS provides first class support for unit testing. Thus we can quickly write tests for our services making them robust and less error prone. ( Business logic ve diğer mantıksal işlemleri service'ler içerisinde yapmanın birçok avantajı vardır: 1 - Concern'leri birbirinden ayırmış oluruz. Herbir component'in ayrı bir görevi vardır ve kendi işini yapmaktan sorumludur. 2 - Herbir component'i test etmek çok daha kolaydır. AngularJS unit testing yapmayı destekler. Service object'lerimiz için hızlıca test'ler yazabiliriz, bu da service object'lerimizi daha sağlam ve hataya az meyilli bir duruma getirmemizi sağlar. )

Consider above diagram. Here we divide our application in two controllers: 1. Profile and 2. Dashboard. Each of these controllers require certain user data from server. Thus instead of repeating the logic to fetch data from server in each controller, we create a User service which hides the complexity. AngularJS automatically inject User service in both Profile and Dashboard controller. Thus our application becomes for modular and testable.
( Yukarıdaki örnek bir uygulamanın diagram'ını inceleyelim. Bu uygulamada 2 tane controller vardır : Profile Controller ve Dashboard Controller. Her iki controller'da da server'dan kullanıcı ile ilgili bilgileri çekmek istiyoruz diyelim. Dolayısıyla aynı kodu her iki controller'da da tekrar tekrar yazmaktansa bir service tanımlarız(user service) ve bu service'i her iki controller'a da aşağıda gösterildiği gibi inject ederiz.
var app = angular.module('myApp', []);
// userService is injected into profileController
app.controller(profileController, function($scope, $userService) { ... }
// userService is injected into dashboardController
app.controller(dashboardController, function($scope, $userService) { ... } )
2. AngularJS internal(built-in) services
AngularJS internally provides many services that we can use in our application. $http is one example (Note: All angularjs internal services starts with $ sign). There are other useful services such as $route, $window, $location etc. (AngularJS bize uygulamamızda kullanabileceğimiz birçok built-in service sağlar. Örnek : $http service, $route service, $window service, $location service. AngularJS'deki tüm built-in service'ler $işareti ile başlar. )
These services can be used within any Controller by just declaring them as dependencies (Bir service'i kullanabilmemiz için önce o service'i controller'ımıza inject etmeliyiz.) For example:
module.controller('FooController', function($http){
//'FooController' isimli controller'a $http service'i inject ederiz.
});
module.controller('BarController', function($window){
//'BarController' isimli controller'a $window service'i inject ederiz.
});
|
3. AngularJS custom services
We can define our own custom services in AngularJS app and use them wherever required ( AngularJS'de custom service tanımlayabiliriz, yani yeni bir service tanımlayıp kullanabiliriz. )
Uygulamamızda yeni bir service object declare etmenin/yaratmanın/veya diğer bir deyişle tanımlamanın 2 farklı yolundan bahsedelim:
service() method'unu kullanarak :
var module = angular.module('myapp', []);
module.service('userService', function()
{
this.users = ['John', 'James', 'Jake'];
});
|
factory() method'unu kullanarak :
module.factory('userService', function(){
var fac = {};
fac.users = ['John', 'James', 'Jake'];
return fac;
});
|
factory() ve service() method'ları, $provider service'inin method'larıdır. Diğer bir deyişle ikisi de provider'dır. Her iki method'u kullanarak da singleton service function/singleton service object tanımlayıp bunu istediğimiz bir controller'da, filter'da, directive'de etc. kullanabiliriz. Bu iki method arasında küçük bir fark vardır,
- service() method'unun aldığı 2.parameter constructor function'dır. Biz service() method'unu kullandığımızda, 2.parametre'deki constructor function' new edilir, yani AngularJS bu constructor function'ı new keyword'ü ile invoke ederek yeni bir object yaratır arka planda; bu constructor function'ın body'sinde kullandığımız this keyword, arka planda otomatik olarak yaratılan bu object'e refer eder, service() method'umuzun body'sinde return ettiğimiz gözükmüyor olsa da service method'umuz bu object'i return eder arka planda.
- factory() method'un body'sinde explicit bir şekilde kendimiz bir object yaratırız ve bu object'i explicit bir şekilde return ederiz. Hatta sadece object değil, fonksiyon ve value de return edebiliriz factory() method'u içinde, service method'da ise bu yoktur.
4. AngularJS Service vs Factory
- AngularJS services are singleton objects. (AngularJS service'ler singleton object'lerdir.)
- These objects are application wide. Thus a service object once created can be used within any other services or controllers etc. ( Service object'ler application scope'u içindedirler yani application-wide'dırlar.
var module = angular.module('myapp', []);
module.service('userService', function(){...})
Module'ü yarattıktan sonra, module.service() veya module.factory() diyerek service object yaratıyoruz/tanımlıyoruz. Yani module scope'u içerisinde geçerli olacak bir service yaratıyoruz diye düşün. )
- Aslınca AngularJS'de service tanımlamanın 4 farklı yolu vardır. Ancak şimdilik sadece iki tanesini inceliyoruz: module.factory() ve module.service() :
module.service( 'serviceName', function );
module.factory( 'factoryName', function );
- When declaring serviceName as an injectable argument you will be provided with an instance of the function. In other words new FunctionYouPassedToService(). This object instance becomes the service object that AngularJS registers and injects later to other services / controllers if required. ( module.service( 'serviceName', function ); -> deyince 2.parametrenin constructor function'ı kullanılarak bir object yaratılır arka planda. AngularJS bu object'i register eder, istersek service object'i diğer service'lere/controller'lara vs. inject eder. )
- When declaring factoryName as an injectable argument you will be provided with the value that is returned by invoking the function reference passed to module.factory. ( module.factory( 'factoryName', function ); -> deyince 2.parametrenin function'ı çağırılır, AngularJS bu function'ın return ettiği object'i register eder. Bu function içerisinde explicit bir şekilde object yaratılır ve return edilir. Bu function object/function/value return edebilir, service() method'unda ise böyle bir özellik yoktur. )
In below example we define MyService in two different ways. Note how in .service, we create service methods using this.methodname. In .factory we created a factory object and assigned the methods to it. ( Aşağıdaki örnekte MyService isimli bir service object'ini iki farklı şekilde yarattık. Soldaki örnekte, this.methodName kullanarak service object'i için method tanımladık. 2.parametredeki constructor function implicit bir şekilde çağırılarak elde edilen object implicitly bir şekilde return edilir. Sağdaki örnekte, 2.parametredeki fonksiyonda explicit bir şekilde boş bir object yaratıyoruz. Sonra bu object için method'lar tanımlıyoruz ve bu object'i return ediyoruz. )
5. Injecting dependencies in services
- Angularjs provides out of the box support for dependency management (AngularJS, dependency'leri yönetecek bir mekanizmaya sahiptir. )
- Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them, whether at run-time or compile-time. ( Dependency injection bir software design pattern'dır. Hard-coded dependency'leri kodumuzdan siler. Dependency'leri run-time'da ve compile-time'da değiştirebilmek mümkündür. Component'lerden birbirlerinden bağımsız hale gelmiş olurlar. )
- We already saw in previous tutorials how to use angularjs dependency management and inject dependencies in controllers. We injected $scope object in our controller class. (Önceki örneklerde, dependency management'ı nasıl kullanacağımız ve controller'lara dependency'leri nasıl inject edeceğimizi öğrendik. Controller'a $scope object inject ettik. )
- Dependency injection mainly reduces the tight coupling of code and create modular code that is more maintainable and testable. AngularJS services are the objects that can be injected in any other Angular construct (like controller, filter, directive etc). You can define a service which does certain tasks and inject it wherever you want. In that way you are sure your tested service code works without any glitch. ( Dependency injection, kodun tight coupling olmasını azaltır, loose coupling sağlar. Daha sürdürülebilir, test edilebilir ve modular kod yazmamızı sağlar. AngularJS'deki service'ler object'lerdir, diğer Angular construct'lara inject edilebilirler. Specific görevleri gerçekleştiren bir service object tanımlayıp, bu object için method'lar tanımlayıp, sonra bu service object'i istediğimiz bir Angular construct'a inject edebiliriz. Dependency injection sayesinde sorunsuz bir şekilde test'lerimizi yapabileceğiz. )
- Like it is possible to inject service object into other angular constructs, you can also inject other objects into service object. One service might be dependence on another. (Bir service object diğer angular construct'lara inject edilebilir demiştik. Ayrıca bir service object diğer service object'lere inject edilebilir, yani bir service object diğer service object'lere dependent olabilir.)
Örnek olarak küçük bir hesap makinesi uygulaması yapalım. Bu uygulama şu fonksiyonelliğe sahip olsun : square(karesini alma) ve cubes(küpünü alma). We will create following entities in AngularJS:
- MathService – A simple custom angular service that has 4 methods: add, subtract, multiply and divide. We will only use multiply in our example. (Tanımlayacağımız bu custom service object 4 tane method'a sahip olacak : add, subtract, multiply and divide . Bu örnekte ise bu service object'in sadece multiply method'unu kullanacağız. )
- CalculatorService – A simple custom angular service that has 2 methods: square and cube. This service has dependency on MathService and it uses MathService.multiply method to do its work. (Tanımlayacağımız bu custom service object 2 tane method'a sahip olacak : square ve cube. Bu service, MathService isimli service'e dependent'dır, yani CalculatorService'e MathService'i inject ederiz. Sonra CalculatorService service object'in içinde, MathService service object'in multiply() method'unu kullanacağız. )
- CalculatorController – This is a simple controller that handle user interactions. For UI we have one textbox to take a number from user and two buttons; one to square another to multiply. ( Bu controller, kullanıcıdan gelen interaction'ları handle eder. Model data'yı view'lere bind eder. )
Bu kodu açıklayalım.
- MathService isimli bir service object tanımlanıyor, bu object 4 tane method'a sahiptir.
- Sonra CalculatorService isimli bir service object tanımlıyoruz, bu service object'e MathService isimli service object'i inject ediyoruz. Yani CalculatorService MathService'e dependent'dır. Bu service object'de 2 tane method tanımlanmıştır :
square ve cube. service object tanımlamak için service() method'unu kullandığımıza dikkat edelim.
- Sonra CalculatorController isimli bir controller tanımlıyoruz, bu controller'a $scope object'i ve CalculatorService service object'ini inject ediyoruz. Bu controller'ın scope'unda doSquare() ve doCube() isimli 2 method tanımladık. Bu method'ları tanımlarken, CalculatorService object'in square() ve cube() method'larından faydalanıyoruz.
Another resource about AngularJS services:
http://www.w3schools.com/angular/angular_services.asp - custom services - customer services inside a filter
2) When you’re using Service, Angular instantiates it behind the scenes with the ‘new’ keyword. Because of that, you’ll add properties to ‘this’ and the service will return ‘this’. When you pass the service into your controller, those properties on ‘this’ will now be available on that controller through your service. .(Service() method'unu tercih edersek, Angular arka planda bu method'a verilen 2.parametredeki constructor function'ı kullanarak bir object yaratır. This keyword'ünü kullanarak bu object'e property'ler eklenir, sonra arka planda this return edilir. Bu service, controller'e inject edildiğinde, service method'unun arka planda return ettiği this keyword'ünün refer ettiği object'e myService aracılığıyla erişebiliriz. )
21 - Providers - helloAngular30_REAL_EXAMPLE_provider_service_factory_promise
https://docs.angularjs.org/guide/services , https://docs.angularjs.org/api/auto/service/$provide ,
http://blog.xebia.com/differences-between-providers-in-angularjs/
http://www.webdeveasy.com/service-providers-in-angularjs-and-logger-implementation/
https://docs.angularjs.org/guide/providers
- The $provide service has a number of methods for registering components with the $injector. Many of these functions are also exposed on angular.Module. ( $provide service object'inin sahip olduğu method'ları kullanarak component'leri $injector'a register ederiz. $provide service object'in sahip olduğu method'ların çoğuna angular.Module de sahiptir, örnek : service(), factory(), value() ve constant())
- Angular services are substitutable objects that are wired together using dependency injection (DI). You can use services to organize and share code across your app. ( Service object'ler, dependency injection kullanılarak bağlanabilirler, birbirlerinin içerisine konulabilirler. Uygulamızdaki kodları organize etmek ve paylaşmak için service'leri kullanabiliriz. )
Angular services are:
- Lazily instantiated – Angular only instantiates a service when an application component depends on it.(Örneğin A diye bir service tanımlıyoruz. A service'i B service'ine dependent olsun, A service'ine B service'i inject edilsin istiyoruz; bunu için şöyle tanımlama yaparız :
var app = angular.module('app', []); // Yeni bir module tanımlıyoruz.
app.service('service1', function ($service2) {
this.title = $service.myVariable;
});
Bu örnekte service1 is dependent on service2. Dolayısıyla service2 object instantiate edilir, ve bu object'in içerisindeki myVariable isimli variable kullanılır. Yani service2'yi daha yukarıda tanımlamış olsak bile service2 hemen instantiate edilmez. Ancak service2'ye yukarıdaki kodda olduğu gibi ihtiyaç duyulduğunda service2 service object'in constructor function'ı çağırılarak bu service'den bir object instantiate edilir. Bu örnekteki component bir service'dir. Başka bir örnek olarak, bir controller bir service'e dependent olsun diyelim, bu durumda controller'ı tanımladığımızda service'in service factory function'ı yani constructor function'ı kullanılarak bir service object yaratılıp controller'a inject edilir. Inject edilmekten kasıt şudur: controller, service object'e refer eden bir variable tutar. Yani bir service, controller vs gibi bir component tanımlarken, bu component'e bağımlı olan component'lerin service factory'leri kullanılarak bir object yaratılıp component'imize bu object'lere refer eden variable'lar inject edilir, diğer bir deyişle component'imize dependent object'ler inject edilir. Eğer bir service'e dependent olan birden fazla component tanımlanırsa, bu durumda daha önce de söylediğimiz gibi service'imiz sadece 1 kez instantiate edilir. Sonraki ihtiyaçlarda instantiate edilen object tekrar kullanılır. )
- Singletons – Each component dependent on a service gets a reference to the single instance generated by the service factory. ( Yukarıdaki örnek koda bakalım. service1, service2'den yaratılan object instance'a refer eder. )
- To use an Angular service, you add it as a dependency for the component (controller, service, filter or directive) that depends on the service. Angular's dependency injection subsystem takes care of the rest. ( Bir component(controller, service, filter or directive)'de bir service'i kullanabilmemiz için, bu service'i component'imize depedency olarak eklemeliyiz. AngularJS'nin DI mekanizması gerisini otomatik olarak halleder. )
- Creating Services
We can define our own services by registering the service's name and service factory function, with an Angular module.( Bir service'in ismini ve service factory function'ı module'e register ederek, service tanımlayabiliriz: module.service(serviceName, serviceFactoryFunction). )
The service factory function generates the single object or function that represents the service to the rest of the application. The object or function returned by the service is injected into any component (controller, service, filter or directive) that specifies a dependency on the service. ( Service factory function, yani $provider service'in service, factory, constant, value fonksiyonlarının aldığı 2. parametre service factory function'dır. Service factory function kullanılarak single bir object veya fonksiyon elde edilir. Buna refer eden bir variable inject edilir service'e dependent olan component'e. )
Registering Services
Services are registered to modules via the Module API. Typically you use the Module factory API to register a service:
var myModule = angular.module('myModule', []);
myModule.factory('myservice', function() { // myservice service is registered to myModule
var shinyNewServiceInstance;
// factory function body that constructs shinyNewServiceInstance
return shinyNewServiceInstance;
});
Note that you are not registering a service instance, but rather a factory function that will create this instance when called.(Module'e service object register etmiyoruz dikkat!!! Module'e factory function'ı(service'in constructor function'ını) register ediyoruz. Bu factory'ye ihtiyaç duyulduğunda bu factory'nin function'ı çağırılarak service instance yaratılacaktır. Yani neymiş biz factory() method'unun aldığı 2.parametre olan fonksiyonu veya service() method'unun aldığı 2.parametre olan constructor function'ı module'e register ederiz. Bu service'den veya factory'den object yaratılması işlemi bu service veya factory'ye ihtiyaç duyulduğu zaman(bunlara dependent bir component tanımlandığında) olur. )
- A factory is a lot like a service in the sense that it is a singleton and dependencies can be specified in the function. A constructor creates a new object so new is called on a service and with a factory you can let the function return anything you want.( Service() method'unu kullanırsak, service method'una verilen 2.parametredeki constructor function kullanılarak yeni bir object yaratılır, bu arka planda AngularJS tarafından yapılır, bizim explicit bir şekilde object yaratmamıza gerek yoktur, tek yapmamız gereken constructor function'ı tanımlamaktır, AngularJS new constructorFunction() diye object yaratacaktır arka planda. Factory() method'unu kullanırsak, fonksiyon içinde explicit bir şekilde object yaratıp bu object'i return edebiliriz, veya başka bir şey de return edebiliriz. Factory() method can return anything! )
- What Is A Provider? A provider is an object with a $get() method. The injector calls the $get method to create a new instance of a service. ( Provider bir service object'dir, bu object $get method'una sahiptir. Uygulamamızın injector'ı $get() method'unu çağırarak bu service'den yeni bir object instance yaratır. Bir AngularJS uygulaması yalnızca bir tane injector'a sahiptir, hatırlayalım. )
$provide service has 6 methods to create custom providers. These providers are available on $provide($provide service object'in sahip olduğu aşağıdaki 6 fonksiyonu kullanarak custom provider'lar yaratırız ) : constant, value, service, factory, decorator, provider.
The Provider can have additional methods which would allow for configuration of the provider. ( $provider service object'in sahip olduğu ekstra method'lar, elde edeceğimiz provider'ı configure etmemizi sağlar.)
AngularJS uses $provide to register new providers. The providers basically create new instances, but only once for each provider. ( yeni bir provider yaratmak için $provider service'i kullanırız. Bir provider'ı(service(),factory(),vs.) kullanarak yeni bir object instance yaratılır, ancak bir provider'ı kullanarak yalnızca bir defa service object yaratılabilir. )
- An Angular service is a singleton object created by a service factory. These service factories are functions which, in turn, are created by a service provider. The service providers are constructor functions. When instantiated they must contain a property called $get, which holds the service factory function.( Bir service, singleton object'dir ve service factory tarafından yaratılır. Yani service(), factory() method'larının aldığı 2.parametre çağırılarak yaratılır. Service factory bu iki method'un aldığı 2.parametredeki fonksiyondur. Module'e register ettiğimiz service'lerin/factory'lerin service factory'leri çağırılarak yaratılan object'ler $get() method'una sahiptir. $get() method'u, service factory function'a sahiptir. )
When you request a service, the $injector is responsible for finding the correct service provider, instantiating it and then calling its $get service factory function to get the instance of the service.
(Bir service'e ihtiyaç duyulduğunda, $injector doğru service provider'ı bulup intantiate etmekten ve sonra onun $get() service factory fonksiyonunu çağırarak bir service object yaratmaktan sorumludur. )
Often services have no configuration options and there is no need to add methods to the service provider. The provider will be no more than a constructor function with a $get property. For these cases the $provide service has additional helper methods to register services without specifying a provider.
constant(name, obj) - registers a value/object that can be accessed by providers and services.
value(name, obj) - registers a value/object that can only be accessed by services, not providers.
factory(name, fn) - registers a service factory function that will be wrapped in a service provider object, whose $get property will contain the given factory function. ( module'e bir service factory function register edilir. Service provider object'in $get() fonksiyonu service factory function'ı içerir. )
service(name, Fn) - registers a constructor function that will be wrapped in a service provider object, whose $get property will instantiate a new object using the given constructor function. (injector'a constructor function register edilir. Service provider object(service object)'in sahip olduğu $get() fonksiyonu constructor fonksiyonunu kullanarak yeni bir object yaratacaktır. Yani biz module'e constructor function'ı register ederiz. Constructor function'ın $get() fonksiyonu çağırılırak yeni bir service object yaratılır. )
decorator(name, decorFn) - registers a decorator function that will be able to modify or replace the implementation of another service.( injector'a bir decorator function register edilir. Bu fonksiyon diğer provider'ların implementation'larını değiştirir veya replace eder. )
What is the difference between the several providers like provider, factory, service, value, constant and decorator? Without this knowledge you could not select the proper provider. We will explain the differences between the providers with examples.
Constant
Bir constant her yere inject edilebilir. Decorator'lar constant'ların değerini değiştiremez.
var app = angular.module('app', []); // Yeni bir module tanımlıyoruz.
app.config(function ($provide) {
$provide.constant('movieTitle', 'The Matrix');
});
AngularJS provides a convenience method for creating a constant. You can rewrite the lines 3-5 to: ( $provide service'in constant() method'unu kullanarak bir constant tanımlayabiliriz yukarıdaki gibi. Alternatif olarak, aşağıdaki gibi tek satırda da bir constant tanımlayabiliriz, burada module'ün constant method'unu kullandığımıza dikkat edelim. )
app.constant('movieTitle', 'The Matrix');
Özet :
Constant şu 2 yolla da tanımlanabilir :
1 -
var app = angular.module('app', []);
app.config( function ($provide) {
$provide.constant('movieTitle', 'The Matrix');
});
2 - app.constant('movieTitle', 'The Matrix');
Register a constant service with the $injector, such as a string, a number, an array, an object or a function. Like the value, it is not possible to inject other services into a constant.
But unlike value, a constant can be injected into a module configuration function (see angular.Module) and it cannot be overridden by an Angular decorator.
Value
A value is nothing more than a simple injectable value. The value can be a string, number but also a function. Value differs from constant in that value can not be injected into configurations, but it can be intercepted by decorators. ( Value provider, configuration block'lara inject edilemez. Value provider'ın değeri decorator'lar tarafından değiştirilebilir, constant'ların ise değiştirilemez. Value provider'ın değeri bir string, sayı veya fonksiyon olabilir. )
var app = angular.module('app', []); // Yeni bir module tanımlıyoruz.
app.config(function ($provide) {
$provide.value('movieTitle', 'The Matrix')
});
AngularJS provides a convenience method for creating a value. ( $provide service'in value() method'unu kullanarak bir value tanımlayabiliriz yukarıdaki gibi. Alternatif olarak, aşağıdaki gibi tek satırda da bir value tanımlayabiliriz, burada module'ün value method'unu kullandığımıza dikkat edelim. )
app.value('movieTitle', 'The Matrix');
Register a value service with the $injector, such as a string, a number, an array, an object or a function. This is short for registering a service where its provider's $get property is a factory function that takes no arguments and returns the value service. That also means it is not possible to inject other services into a value service.
Value services are similar to constant services, except that they cannot be injected into a module configuration function (seeangular.Module) but they can be overridden by an Angular decorator.
Service
A service is an injectable constructor. A service is a singleton and will only be created once by AngularJS. Services are a great way for communicating between controllers like sharing data. ( Service, injectable bir function constructor'dır. service method'unun aldığı 2.parametre bir function constructor'dır, dolayısıyla return statement yoktur çünkü constructor'lar bir şey return etmez. Bir yere service'i inject etmemiz demek, constructor function'ı inject etmemiz demektir. Service bir singleton object'dir, anonymous function constructor kullanılarak yaratılır yani, yanlış değilsem inject edilen constructor function kullanılarak bu service'den yalnızca bir defaya mahsus bir object yaratılır, bu object ne zaman yaratılır peki? Bu object'e ihtiyaç duyulduğu zaman, lazy evaluation yani. Controller'lar birbirleriyle haberleşmek için service'leri kullanırlar demek istemiş sanırım yukarıda )
var app = angular.module('app' ,[]); // Yeni bir module tanımlıyoruz.
app.config(function ($provide) {
$provide.service('movie', function () {
this.title = 'The Matrix';
});
});
AngularJS provides a convenience method for creating a service. ( Yukarıda, $provide service'in service() method'unu kullanarak bir service provider tanımladık. Alternatif olarak, aşağıdaki gibi kısa yoldan da bir service provider tanımlayabiliriz, aşağıda module'ün service() method'unu kullandığımıza dikkat edelim. )
app.service('movie', function () {
this.title = 'The Matrix';
});
Register a service constructor, which will be invoked with new to create the service instance. This is short for registering a service where its provider's $get property is a factory function that returns an instance instantiated by the injector from the service constructor function.
Internally it looks a bit like this:
{
$get: function() {
return $injector.instantiate(constructor);
}
}
Factory
Register a service factory, which will be called to return the service instance. This is short for registering a service where its provider consists of only a $get property, which is the given service factory function. You should use $provide.factory(getFn) if you do not need to configure your service in a provider. ( service factory, yani factory method'unun aldığı 2.parameter injector'a register edilir. Service object return etmek için bu service factory çağırılır. Provider() method'unu kullanarak bir service register etmek daha detaylı bir iştir, factory method'unu kullanarak service register etmek ise kısayoldur. factory() method'unun aldığı 2.parametredeki fonksiyonun return ettiği object otomatik olarak bir $get property içerir. $get property'si, 2.parametredeki fonksiyonu içerir. Eğer return edilecek object'i configure etmek gibi bir derdimiz yoksa factory() veya service() method'unu kullanabiliriz, ancak return edilecek object'i configure edebilmek istiyorsak provider() method'unu kullanmalıyız. )
A factory is an injectable function. A factory is a lot like a service in the sense that it is a singleton and dependencies can be specified in the function. The difference between a factory and a service is that a factory injects a plain function so AngularJS will call the function and a service injects a constructor. A constructor creates a new object so new is called on a service and with a factory you can let the function return anything you want. As you will see later on, a factory is a provider with only a $get method. ( Factory, injectable bir function'dır. factory() method'unun aldığı 2.parametre bir fonksiyondur, bu fonksiyonda return statement olmak zorundadır. Bir yere factory'yi inject etmemiz demek, fonksiyonu inject etmemiz demektir. Factory bir singleton object'dir, factory'ye ihtiyaç duyulduğu anda AngularJS bu function'ı otomatik olarak çağıracaktır ve bu function'ın return ettiği değer elde edilecektir, lazy evaluation yani. Factory, bir object return etmek zorunda değildir, her şey return edebilir. Service'de ise, AngularJS constructor function'ı kullanarak otomatik olarak bir object yaratır ihtiyaç duyulduğu zaman. )
var app = angular.module('app', []); // Bir module tanımladık.
app.config(function ($provide) {
$provide.factory('movie', function () {
return {
title: 'The Matrix';
}
});
});
AngularJS also provides a convenience method for creating a factory. ( Yukarıda, $provide service object'in factory() method'unu kullanarak bir factory provider tanımladık. Alternatif olarak, aşağıdaki gibi kısa yoldan da bir factory provider tanımlayabiliriz, aşağıda module'ün factory() method'unu kullandığımıza dikkat edelim. )
app.factory('movie', function () { 
return {
title: 'The Matrix';
}
});
Decorator
A decorator can modify or encapsulate other providers. There is one exception and that a constant cannot be decorated. ( Bir decorator, diğer tüm provider'ları modify edebilir, constant provider hariç. )
var app = angular.module('app', []); // Bir module tanımladık.
app.value('movieTitle', 'The Matrix'); // bir value provider tanımladık
app.config(function ($provide) {
$provide.decorator('movieTitle', function ($delegate) {
return $delegate + ' - starring Keanu Reeves';
});
});
$provide service object'i kullanarak bir decorator tanımlıyoruz. Yukarıda önce movieTitle isimli bir value provider tanımladık. Sonra module'ün config method'unu kullandık. Config block'a önce $provide service'i inject ettik. Sonra ise $provide service'in decorator() method'unu kullanarak bir custom decorator provider tanımladık. $provide service object'in decorator() method'una verdiğimiz 1. parametre modify etmek istediğimiz provider'ın ismi, 2.parametre ise bir fonksiyondur, bu fonksiyon argument olarak $deletegate service object'i alır, ve şunu return eder: $delegate(yani movieTitle variable'ının current değeri)+(movieTitle isimli provider'a eklemek istediğimiz değer).
$delegate - The original service instance, which can be replaced, monkey patched, configured, decorated or delegated to.
Provider
https://docs.angularjs.org/guide/providers link'ini açıklamadım ama çok önemli buraya gözat.
Provider() method'u hem service hem de factory gibi düşünülebilir. provider method'unun aldığı 2.parametre,
- object return eden bir fonksiyon olabilir tıpkı bir factory'deki gibi.
- bir constructor function olabilir, service'deki gibi this keyword'ünü kullanarak object için property'ler set edebiliriz.
A provider is the most sophisticated method of all the providers. It allows you to have a complex creation function and configuration options. A provider is actually a configurable factory. The provider accepts an object or a constructor.
Registers a provider function with the $injector. Provider functions are constructor functions, whose instances are responsible for "providing" a factory for a service. ( provider() fonksiyonuna verilen 2.parametre constructor veya object'dir, bu parametre $injector'a register eder. )
Service provider names start with the name of the service they provide followed by Provider. For example, the $log service has a provider called $logProvider.
( Provider("someName",function...) method'unu kullanarak bir service tanımladık diyelim. Bu service provider'ın adı artık someNameProvider'dır. Bu service'i başka bir component'e inject etmek istediğimizde someNameProvider ismini kullanarak inject edeceğiz. )
Service provider objects can have additional methods which allow configuration of the provider and its service. Importantly, you can configure what kind of service is created by the $get method, or how that service will act. For example, the $logProvider has a method debugEnabled which lets you specify whether the $log service will log debug messages to the console or not. (Provider object'lerin sahip olduğu ekstra method'lar, provider'ın ve onun service'inin configure edilebilmesini sağlar. Örneğin, $logProvider debugEnabled isimli bir method'a sahiptir, bu method $log service'inin debug mesajlarını console'a log'layıp log'lamamasını belirler. )
var app = angular.module('app', []);
app.provider('movie', function ()
{
var version;
return {
setVersion: function (value) {
version = value;
},
$get: function () {
return {
title: 'The Matrix' + ' ' + version
}
}
}
});
app.config(function (movieProvider) {
movieProvider.setVersion('Reloaded');
});
( provider() method'u kullanılarak önce movie isimli bir provider tanımlanmıştır. Sonra config method'u kullanılarak config block'a movieProvider inject edilmiştir. Bu object'in setVersion() method'u çağırılarak movieProvider() configure edilir, version isimli variable'ı değiştirilir. movie isimli provider'a dependent bir component tanımlandığında configure edilmiş olan bu provider'ın $get() method'u çağırılarak bu provider'ın service factory function'ı yani constructor function'ı kullanılarak bir object yaratılır. )
Provider fonksiyonunun aldığı 2.parametre object veya constructor olabilir:
Provider() method'u hem service hem de factory gibi düşünülebilir. provider method'unun aldığı 2.parametre,
- object return eden bir fonksiyon olabilir tıpkı bir factory'deki gibi.
- bir constructor function olabilir, service'deki gibi this keyword'ünü kullanarak object için property'ler set edebiliriz.
Yukarıdaki ve aşağıdaki örnek bunlara bir örnektir, iki farklı şekilde provider yaratmak mümkündür.
More than that, $provide.service() and $provide.factory() are actually an easy way to use $provide.provider():
$provide.service() and $provide.factory() are actually $provide.provider()
$provide.service('serviceName', function() {
this.name = 'The Catcher in the Rye';
this.author = 'J. D. Salinger';
});
// Equals to
$provide.provider('serviceName', function() {
this.$get = function($injector) {
return $injector.instantiate(function() {
this.name = 'The Catcher in the Rye';
this.author = 'J. D. Salinger';
});
};
});
$provide.factory('factoryName', function() {
return { name: 'The Catcher in the Rye', author: 'J. D. Salinger' };
});
// Equals to
$provide.provider('serviceName', function() {
this.$get = function($injector) {
return $injector.invoke(function() {
return { name: 'The Catcher in the Rye', author: 'J. D. Salinger' };
});
};
});
Besides of creating the service, service provider allows to configure the service on module.config() block. Look on the following appColorexample service that is defined by a service provider:
Sample `appColor` service provider
$provide.provider('appColor', function() {
var color = 'Green';
this.setColor = function(newColor) {
color = newColor;
};
this.$get = function() {
return color;
};
});
Whenever we ask from Angular to inject appColor, we get the color variable that returned from the $get method. But on module.config()blocks we can ask for appColorProvider which exposes the provider and all it’s methods and attributes. This let us configure the service before other code consumes it:
`appColor` configuration and usage
module.config(['appColorProvider', function(appColorProvider) {
appColorProvider.setColor('Blue');
});
...
...
module.run(['appColor', function(appColor) {
// Will log: 'Application color is Blue'
console.log('Application color is ' + appColor);
});
As you can see, service provider gave us access to the “provider” part, where we can set methods or variables and which can be accessed during configuration only.
Summary
- All the providers are instantiated only once. That means that they are all singletons. (Tüm provider'lar anonymous function'lardır, anonymous function'lar sadece bir kere çağırılabilir çünkü bu function'ların bir ismi yoktur. Dolayısıyla anonymous fonksiyonlar sadece bir kere çağırılabileceği için tüm provider'lar da sadece bir defa instantiate edilebilir. )
- All the providers except constant can be decorated. ( Constant hariç tüm provider'lar decorate edilebilir/modify edilebilir. )
- A constant is a value that can be injected everywhere. The value of a constant can never be changed. ( Constant her yere inject edilebilir. Constant decorate edilemez. )
- A value is just a simple injectable value.( Value, inject edilebilir bir değerdir. )
- A service is an injectable constructor. ( Service, inject edilebilir bir constructor'dır. )
- A factory is an injectable function. ( Factory, inject edilebilir bir fonksiyondur. )
- A decorator can modify or encapsulate other providers except a constant. ( Decorator, diğer provider'ları modify edebilir veya encapsulate edebilir, constant hariç. )
- A provider is a configurable factory.(Provider, configure edilebilir bir factory'dir.)
22 - AngularJS: Factory vs Service vs Provider
http://tylermcginnis.com/angularjs-factory-vs-service-vs-provider/
http://stackoverflow.com/questions/14324451/angular-service-vs-angular-factory/15914263#15914263
Angular provides us with three ways to create and register our own service.
1) Factory 2) Service 3) Provider
TL;DR (Summary)
1) When you’re using a Factory you create an object, add properties to it, then return that same object. When you pass this factory into your controller, those properties on the object will now be available in that controller through your factory.(Factory() method'unda, bir objcet yaratılır, bu object'e property'ler eklenir, sonra bu object return edilir. Bu factory controller'e inject edildiğinde, factory method'unun return ettiği service isimli object'in property'lerine myFactory aracılığıyla erişebiliriz. )
app.controller('myFactoryCtrl', function($scope, myFactory){
$scope.artist = myFactory.getArtist();
});
app.factory('myFactory', function(){
var _artist = 'Shakira';
var service = {};
service.getArtist = function(){
return _artist;
}
return service;
});
2) When you’re using Service, Angular instantiates it behind the scenes with the ‘new’ keyword. Because of that, you’ll add properties to ‘this’ and the service will return ‘this’. When you pass the service into your controller, those properties on ‘this’ will now be available on that controller through your service. .(Service() method'unu tercih edersek, Angular arka planda bu method'a verilen 2.parametredeki constructor function'ı kullanarak bir object yaratır. This keyword'ünü kullanarak bu object'e property'ler eklenir, sonra arka planda this return edilir. Bu service, controller'e inject edildiğinde, service method'unun arka planda return ettiği this keyword'ünün refer ettiği object'e myService aracılığıyla erişebiliriz. )
app.controller('myServiceCtrl', function($scope, myService){
$scope.artist = myService.getArtist();
});
app.service('myService', function(){
var _artist = 'Nelly';
this.getArtist = function(){
return _artist;
}
});
- Here is the same simple object created using a service and a factory(Yukarıda tanımladığımız service provider ve factory provider'ı biraraya getirip inceleyelim. Aşağıdaki örnekte hem service hem factory aynı object'i yaratır. ):
angular.module('app', [])
.service('helloService', function() {
this.sayHello = function() {
return "Hello!";
}
})
.factory('helloFactory', function() {
return {
sayHello: function() {
return "Hello!";
}
}
});
- Services and factories are similar to one another. Both will yield a singleton object that can be injected into other objects, and so are often used interchangeably. They are intended to be used semantically to implement different design patterns. Services are newable constructors. Factories are simply called and return an object.
3 - Providers are the only service you can pass into your .config() function. Use a provider when you want to provide module-wide configuration for your service object before making it available.
NON TL;DR (Detailed explanation)
In order to extensively show the difference between a Factory, Service, and Provider, we’re going to build the same service in three separate ways. The services are going to utilize the iTunes API as well as promises with $q.
1) Factory
Factories are the most popular way to create and configure a service. There’s really not much more than what the TL;DR said. You just create an object, add properties to it, then return that same object. Then when you pass the factory into your controller, those properties on the object will now be available in that controller through your factory. A more extensive example is below.
First we create an object, then return that object like so.

Now whatever properties we attach to ‘service’ will be available to us when we pass ‘myFactory’ into our controller.
Now let’s add some ‘private’ variables to our callback function. These won’t be directly accessible from the controller, but we will eventually set up some getter/setter methods on ‘service’ to be able to alter these ‘private’ variables when needed. Notice that we’re not attaching those variables/function to ‘service’. We’re simply creating them in order to either use or modify them later. (baseURL, _artist, finalURL ve makeURL() private variable'lardır. Bu variable'ları return edilecek olan service object'i içerisinde tanımlamadığımıza dikkatinizi çekerim. Bu variable'lara controller'dan doğrudan erişilemez. Bu variable'ları modify edebilmek için setter ve getter method'lar yazacağız sonra.)
baseUrl is the base URL that the iTunes API requires
_artist is the artist we wish to lookup ( aramak istediğimiz artist- input box'a girilen değer )
_finalUrl is the final and fully built URL to which we’ll make the call to iTunes
makeUrl is a function that will create and return our iTunes friendly URL.
Now that our helper/private variables and function are in place, let’s add some properties to the ‘service’ object. Whatever we put on ‘service’ we’ll be able to directly use in whichever controller we pass ‘myFactory’ into. ( Private variable'larımızı yazdık. Şimdi de service isimli object'e property'ler ekleyelim, bu object'e ekleyeceğimiz property'lere, bu factory'yi inject edeceğimiz controller içerisinden doğrudan erişebileceğiz.
- setArtist accepts an artist and allows you to set the artist
- getArtist returns the artist
- callItunes first calls makeUrl() in order to build the URL we’ll use with our $http request. Then it sets up a promise object, makes an $http request with our final url, then because $http returns a promise, we are able to call .success or .error after our request. We then resolve our promise with the iTunes data, or we reject it with a message saying ‘There was an error’. In summary, this method calls the iTunes API with our created URL. This method is going to return a promise that will fulfill once the data has come back from the iTunes API.
Now our factory is complete. We are now able to inject ‘myFactory’ into any controller and we’ll then be able to call our methods that we attached to our service object (setArtist, getArtist, and callItunes). ( Artık factory'miz kullanılmaya hazırdır. myFactory'yi istediğimiz controller'a inject edebilir ve service isimli object'e koyduğumuz tüm method'larımızı controller'dan doğrudan çağırabiliriz. )
In the controller above we’re injecting in the ‘myFactory’ service. We then set properties on our $scope object that are coming from data from ‘myFactory’. Because callItunes is returning a promise, we are able to use the .then() method and only set $scope.data.artistData once our promise is fulfilled with the iTunes data. You’ll notice our controller is very ‘thin’. All of our logic and persistent data is located in our service, not in our controller. ( Yukarıdaki kodda controller'a myFactory'yi inject ettik. Sonra controller'ızın scope'unda property'ler set etmek için myFactory'den gelen verileri kullandık. callITunes() method'u promise return eder, promise başarılı return etmişse $scope.data.artistData set edilir. Bu örnekte, controller'ımızda ağır iş yapmadığıza dikkatinizi çekerim. Tüm ağır işi ağır yükü business logic'i service'imizde yani factory'mizde yaptık. )
2) Service
Perhaps the biggest thing to know when dealing with creating a Service is that that it’s instantiated with the ‘new’ keyword. For those of you with a limited background in JavaScript or for those who aren’t too familiar with what the ‘new’ keyword actually does, let’s review some JavaScript fundamentals that will eventually help us in understanding the nature of a Service.
First let’s create our Constructor. Now whenever we invoke the Person function using the ‘new’ keyword, ‘this’ will be bound to the newly created object. (Örnek olarak bir, JavaScript constructor function tanımlayalım. new keyword'ü ile Person fonksiyonunu invoke ettiğimizde, yeni yaratılan object'e this refer eder. )
Now let’s add a method onto our Person’s prototype so it will be available on every instance of our Person ‘class’.
Now that we have our Person constructor function and our sayName function on its prototype, let’s actually create an instance of Person then call the sayName function.
All :
Unlike what we originally did with the Factory example, we don’t need to create an object then return that object because, like mentioned many times before, we used the ‘new’ keyword so the interpreter will create that object, have it delegate to it’s prototype, then return it for us without us having to do the work.
First things first, let’s create our ‘private’ and helper function.
Now, we’ll attach all of our methods that will be available in our controller to ‘this’. Just like in our factory, setArtist, getArtist, and callItunes will be available in whichever controller we pass myService into.
Like I mentioned before, once you really understand what ‘new’ does, Services are almost identical to factories in Angular.
3) Provider
The biggest thing to remember about Providers is that they’re the only service that you can pass into the app.config portion of your application. This is of huge importance if you’re needing to alter some portion of your service object before it’s available everywhere else in your application. . Use a provider when you want to provide module-wide configuration for your service object before making it available. Although very similar to Services/Factories, there are a few differences which we’ll discuss. (Service'den bir instance yaratmadan önce service'i configure edebilmek/modify edebilmek istiyorsak provider() method'unu kullanmalıyız. config() fonksiyonuna parametre olarak verilebilecek tek service provider'lardır, böylece service configure edilebilir/modify edilebilir. Provider, configure factory'dir demiştik daha önce, hatırlayalım. Yani bir object return ederler. Aşağıdaki koda bakalım. Hani object return etmemiş dediğinizi duyar gibiyim. Dikkaaat. $get() fonksiyonu object return edecektir. )
The variables below are our ‘private’ and helper function.
You can think of Providers as having three sections:
- The first section is the ‘private’ variables/functions that will be modified/set later (shown above).
- The second section is the variables/functions that will be available in your app.config function and are therefore available to alter before they’re available anywhere else (also shown above). It’s important to note that those variables need to be attached to the ‘this’ keyword. In our example, only ‘thingFromConfig’ will be available to alter in the app.config.
- The third section (shown below) is all the variables/functions that will be available in your controller when you pass in the ‘myProvider’ service into that specific controller.
Aslında 2. ve 3. kısım aynıdır, provider'dan bir instance yaratıldığında elde edilecek object'in sahip olacağı property'leri this keyword'ünü kullanarak set ederiz. provider method'unu kullanarak bir provider diğer bir deyişle bir service tanımladık diyelim. Bu provider'a dependent bir module tanımlandığında, bu provider'dan bir instance yaratılır, $get() method'u çağırılır.
When creating a service with Provider, the only properties/methods that will be available in your controller are those properties/methods which are returned from the $get() function. The code below puts $get on ‘this’ (which we know will eventually be returned from that function). Now, that $get function returns all the methods/properties we want to be available in the controller. Here’s a code example.
Now just like in our factory and Service, setArtist, getArtist, and callItunes will be available in whichever controller we pass myProvider into. Here’s the myProvider controller (which is almost exactly the same as our factory/Service controller). ( Controller'ımızda bu provider'ı dependent olarak belirttik diyelim. Bu durumda provider'dan bir instance yaratılır, bu provider için bir config() method'u varsa configuration işlemleri instance üzerinde gerçekleştirilir sonra bu instance'ın $get() method'u çağırılır, $get() method'Unun return ettiği object controller'a inject edilir. )
(Bu örnekte, myProviderCtrl myProvider'a dependent'dır. myProvider'dan bir instance yaratılır. Bu instance'a $get() method'u ve thingFromConfig variable eklenir. Sonra app.config() method'unda, myProviderProvider'ın yani current instance'ımızın thingFromConfig variable'ının değeri değiştirilir. Sonra bu instance'ın $get() method'u çağırılır, bu method'un return ettiği object controller'ımıza inject edilir. Inject edilen bu object'de thingOnConfig isimli bir variable tanımlanır, bu variable'a provide instance'daki thingFromConfig(this keyword'ünün refer ettiği variable)'in değeri assign edilir. )
As mentioned before, the whole point of creating a service with Provider is to be able to alter some variables through the app.config function before the final object is passed to the rest of the application. Let’s see an example of that.
Now you can see how ‘thingFromConfig’ is as empty string in our provider, but when that shows up in the DOM, it will be ‘This sentence was set…’. ( Tanımladığımız provider'da thingFromConfig isimli variable empty string olmasına rağmen, ekranda bu variable'ın değeri ‘This sentence was set…’ olarak gözükür. )
25 -
http://stackoverflow.com/questions/15666048/angularjs-service-vs-provider-vs-factory
All Services are singletons; they get instantiated once per app. They can be of any type, whether it be a primitive, object literal, function, or even an instance of a custom type.
The value, factory, service, constant, and provider methods are all providers. They teach the Injector how to instantiate the Services.
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.
- The Value Recipe is the simplest case, where you instantiate the Service yourself and provide the instantiated value to the injector.
- The Factory recipe gives the Injector a factory function that it calls when it needs to instantiate the service. When called, the factory function creates and returns the service instance. The dependencies of the Service are injected as the functions' arguments. So using this recipe adds the following abilities:
- Ability to use other services (have dependencies)
- Service initialization
- Delayed/lazy initialization
- The Service recipe is almost the same as the Factory recipe, but here the Injector invokes aconstructor with the new operator instead of a factory function.
- The Provider recipe is usually overkill. It adds one more layer of indirection by allowing you to configure the creation of the factory.
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. This is usually interesting only for reusable services whose behavior might need to vary slightly between applications.
- The Constant recipe is just like the Value recipe except it allows you to define services that are available in the config phase. Sooner than services created using the Value recipe. Unlike Values, they cannot be decorated using decorator.
23 - The difference between Service, Provider, and Factory in AngularJS
http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/
http://www.angularjshub.com/examples/modules/registeringprovider/ açıklamadım ama güzel örnek.
http://anandmanisankar.com/posts/angularjs-provider-subsystem/ açıklamadım ama güzel örnek.
If you think they are similar – you’re right. They are very similar. In fact, they are all the the same thing. They are all providers. The factory and the service are just special cases of the provider, but you can accomplish everything you want using just provider.
The Provider
We’re going to create a provider that returns a value and simply display that value. Provider() can return anything.
<body ng-app="MyModule">
<div ng-controller="MyController"></div>
</body>
var mod = angular.module("MyModule", []);
mod.provider("myProvider", function() {
this.$get = function() {
return "My Value";
};
});
mod.controller("MyController", function(myProvider) {
console.log("MyController - myProvider: " + myProvider);
});
CONSOLE OUTPUT
MyController - myProvider: My Value
Angular only gets the value once – ever
Note in further code samples I’m going to exclude the <body> tag and the definition of the mod for the purpose of keeping the code excerpts short and to the point.
Note that angular only “gets” the value once, no matter how many times the provider is injected. That means it calls $get() only once ever, stores the value provided by $get(), and gives you that same stored value every time.
To show you what I mean I’ll create another controller and inject the provider again with a console statement so that you can see what’s happening. $get() function was only called once as you can see in the below example. (Örnek olarak aşağıda bir provider tanımlıyoruz ve bu provider'ı 2 farklı controller'a inject ediyoruz. Output'u incelersek $get() fonksiyonunun yalnızca bir defa çağırıldığını anlarız. )
<div ng-controller="MyController"></div>
<div ng-controller="MyController2"></div>
mod.provider("myProvider", function() {
this.$get = function() {
console.log("MyProviderFunction.$get() called.");
return "My Value";
};
});
mod.controller("MyController", function(myProvider) {
console.log("MyController - myProvider: " + myProvider);
});
mod.controller("MyController2", function(myProvider) {
console.log("MyController2 - myProvider: " + myProvider);
});
CONSOLE OUTPUT
MyProviderFunction.$get() called.
MyController - myProvider: My Value
MyController2 - myProvider: My Value
A Factory
With a factory you just provide the function body for the $get method and Angular does the rest.
mod.factory("myProvider", function() { // CHANGED “provider" to “factory"
console.log("Factory function called.");
return "My Value";
});
mod.controller("MyController", function(myProvider) {
console.log("MyController - myProvider: " + myProvider);
});
mod.controller("MyController2", function(myProvider) {
console.log("MyController2 - myProvider: " + myProvider);
});
CONSOLE OUTPUT
Factory function called.
MyController - myProvider: My Value
MyController2 - myProvider: My Value
Yukarıdaki örnekteki factory() method string return eder. Ancak genellikle tanımladığımız factory method'ları object return edecektir. Aşağıdaki örnekte, getValue() isimli bir fonksiyon içeren MyObject isimli bir constructor function tanımladık. Ancak factory() method'unun 2.parametresine MyObject fonksiyonunu veremeyiz! Çünkü factory method'undan sadece bir defa instance yaratılacaktır dolayısıyla factory method'unun 2.parametresi anonymous function olmalıdır.
Aşağıdaki örnekte, new keyword'ü ve bu constructor function kullanılarak yeni bir object yaratılacaktır. factory() method'unun 2.parametresine tanımladığımız MyObject isimli constructor function'ı parametre olarak verdik.
function MyObject() { // ADDED our object constructor
this.getValue = function() {
return "My Value";
};
}
mod.factory("myProvider", function() {
console.log("Factory function called.");
return new MyObject(); // CREATE an instance of our object
});
mod.controller("MyController", function(myProvider) {
console.log("MyController - myProvider: " + myProvider.getValue()); // CHANGED to call getValue()
});
mod.controller("MyController2", function(myProvider) {
console.log("MyController2 - myProvider: " + myProvider.getValue()); // CHANGED to call getValue()
});
CONSOLE OUTPUT
Factory function called.
MyController - myProvider: My Value
MyController2 - myProvider: My Value
Yukarıdaki gibi yapmaktansa, tanımladığımız fonksiyon'u inline hale getiriririz yani anonymous fonksiyon haline getiririz ve factory() method'unun 2. parametresine bu anonymous fonksiyonu veririz aşağıdaki gibi.
mod.factory("myProvider", function() {
console.log("Factory function called.");
return new function() { // INLINED our object constructor
this.getValue = function() {
return "My Value";
};
};
});
mod.controller("MyController", function(myProvider) {
console.log("MyController - myProvider: " + myProvider.getValue());
});
mod.controller("MyController2", function(myProvider) {
console.log("MyController2 - myProvider: " + myProvider.getValue());
});
Service
Aynı örneği service kullanarak yapalım :
mod.service("myProvider", function() { // CHANGED "factory" to "service"
this.getValue = function() {
return "My Value";
};
});
mod.controller("MyController", function(myProvider) {
console.log("MyController - myProvider: " + myProvider.getValue());
});
mod.controller("MyController2", function(myProvider) {
console.log("MyController2 - myProvider: " + myProvider.getValue());
});
CONSOLE OUTPUT
MyController - myProvider: My Value
MyController2 - myProvider: My Value
Provider vs Factory vs Service
So in summary, provider, factory, and service are all providers. A factory is a special case of a provider when all you need in your provider is a $get() function. It allows you to write it with less code. A service is a special case of a factory when you want to return an instance of a new object, with the same benefit of writing less code.
When to use one versus the other?
Örneğin varolan bir object'i return etmek istiyorsak, factory() method'unu kullanmalıyız.
mod.factory("myProvider", function() {
console.log("Factory function called.");
return new SomeMessageBoxClass("custom argument");
});
Provider ve factory arasında nasıl karar veririz peki? Generate edilecek object'i generate edilmeden önce configure edebilmek istiyorsak,provider() seçmeliyiz. Provider'ı configure etmek için module.config() method'unu kullanmalıyız. config() method'una provider'ı verirken provider'ın isminin sonuna Provider getirilmiş string'i parametre olarak vermeliyiz.
Here is an example of how you would do that:
mod.provider("myProvider", function() {
this.value = "My Value";
this.setValue = function(newValue) {
this.value = newValue;
};
this.$get = function() {
return this.value;
};
});
mod.controller("MyController", function(myProvider) {
console.log("MyController - myProvider: " + myProvider);
});
mod.config(function(myProviderProvider) { // ADDED config section
// Note the extra "Provider" suffix
myProviderProvider.setValue("New Value");
});
There is one additional provider : value provider.
// Example where factory depends on a "value" provider
mod.value("multiple", 3);
mod.factory("value", function(multiple) {
return 10 * multiple;
});
// Example where factory depends on external data
mod.factory("value", function(multiple) {
var multiple = getDateFromExternalPage();
return 10 * multiple;
});
Summary :
No comments:
Post a Comment