From 4cc078a9154a3eb0a007c92442005c8fc7743954 Mon Sep 17 00:00:00 2001 From: Tim Ruffles Date: Sun, 6 Oct 2013 23:01:03 +0100 Subject: [PATCH] docs($provider): new example, more guidance on factory() vs service() Currently $provide's example seems awkward. These examples are more real-world - they use an injected service, and the service defined has a good reason to be a singleton. There's quite a lot of confusion around $provide, so I thought it'd be good to make this page clearer. Tests for example: http://jsbin.com/EMabAv/1/edit?js,output Confusion on SO: http://stackoverflow.com/search?q=angularjs+service+vs+factory --- src/auto/injector.js | 90 +++++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 26 deletions(-) diff --git a/src/auto/injector.js b/src/auto/injector.js index 03e8025fa7de..2606f2f9c38d 100644 --- a/src/auto/injector.js +++ b/src/auto/injector.js @@ -276,39 +276,76 @@ function annotate(fn) { * a service. The Provider can have additional methods which would allow for configuration of the provider. * *
- *   function GreetProvider() {
- *     var salutation = 'Hello';
- *
- *     this.salutation = function(text) {
- *       salutation = text;
- *     };
- *
- *     this.$get = function() {
- *       return function (name) {
- *         return salutation + ' ' + name + '!';
+ *   function TrackingProvider() {
+ *     this.$get = function($http) {
+ *       var observed = {};
+ *       return {
+ *         event: function(event) {
+ *           var current = observed[event];
+ *           return observed[event] = current ? current + 1 : 1;
+ *         },
+ *         save: function() {
+ *           $http.post("/track",observed);
+ *         }
  *       };
  *     };
  *   }
  *
- *   describe('Greeter', function(){
- *
+ *   describe('Tracking', function() {
+ *     var mocked;
  *     beforeEach(module(function($provide) {
- *       $provide.provider('greet', GreetProvider);
+ *       $provide.provider('tracking', TrackingProvider);
+ *       mocked = {post: jasmine.createSpy('postSpy')};
+ *       $provide.value('$http',mocked);
  *     }));
- *
- *     it('should greet', inject(function(greet) {
- *       expect(greet('angular')).toEqual('Hello angular!');
+ *     it('allows events to be tracked', inject(function(tracking) {
+ *       expect(tracking.event('login')).toEqual(1);
+ *       expect(tracking.event('login')).toEqual(2);
  *     }));
  *
- *     it('should allow configuration of salutation', function() {
- *       module(function(greetProvider) {
- *         greetProvider.salutation('Ahoj');
- *       });
- *       inject(function(greet) {
- *         expect(greet('angular')).toEqual('Ahoj angular!');
- *       });
- *     });
+ *     it('posts to save', inject(function(tracking) {
+ *       tracking.save();
+ *       expect(mocked.post.callCount).toEqual(1);
+ *     }));
+ *   });
  * 
+ * + * There are also shorthand methods to define services that don't need to be configured beyond their `$get()` method. + * + * `service()` registers a constructor function which will be invoked with `new` to create the instance. You can specify services that will be provided by the injector. + * + *
+ *    function TrackingProvider($http) {
+ *      var observed = {};
+ *      this.event = function(event) {
+ *        var current = observed[event];
+ *        return observed[event] = current ? current + 1 : 1;
+ *      };
+ *      this.save = function() {
+ *        $http.post("/track",observed);
+ *      };
+ *    }
+ *    $provider.service('tracking',TrackingProvider);
+ *  
+ * + * `factory()` registers a function whose return value is the instance. Again, you can specify services that will be provided by the injector. + * + *
+ *    function TrackingProvider($http) {
+ *      var observed = {};
+ *      return {
+ *        event: function(event) {
+ *          var current = observed[event];
+ *          return observed[event] = current ? current + 1 : 1;
+ *        },
+ *        save: function() {
+ *          $http.post("/track",observed);
+ *        }
+ *      };
+ *    }
+ *    $provider.factory('tracking',TrackingProvider);
+ *  
+ * */ /** @@ -336,7 +373,7 @@ function annotate(fn) { * @methodOf AUTO.$provide * @description * - * A short hand for configuring services if only `$get` method is required. + * A service whose instance is the return value of `$getFn`. Short hand for configuring services if only `$get` method is required. * * @param {string} name The name of the instance. * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand for @@ -351,7 +388,7 @@ function annotate(fn) { * @methodOf AUTO.$provide * @description * - * A short hand for registering service of given class. + * A service whose instance is created by invoking `constructor` with `new`. A short hand for registering services which use a constructor. * * @param {string} name The name of the instance. * @param {Function} constructor A class (constructor function) that will be instantiated. @@ -619,3 +656,4 @@ function createInjector(modulesToLoad) { }; } } +