diff options
| author | Pete Bacon Darwin | 2013-10-10 16:46:59 +0100 |
|---|---|---|
| committer | Pete Bacon Darwin | 2013-10-10 18:22:52 +0100 |
| commit | 770353df1956ab45bdbe45a4d5040caa40bf880f (patch) | |
| tree | fb6ec18112ff9056f8a8daffefa939ac0c476616 | |
| parent | 85b7d24357a59876810d8b2494bd2bfbb920a5da (diff) | |
| download | angular.js-770353df1956ab45bdbe45a4d5040caa40bf880f.tar.bz2 | |
docs($provide): improve docs and examples further
Improve the "tracking" service example by adding a configuration option.
Get better formatting of the generated code samples using <pre> tags.
Move the detailed explanations into each function's documentation block.
Improve the overview and list the constituent functions by significance.
Closes #4302
| -rw-r--r-- | src/auto/injector.js | 293 |
1 files changed, 204 insertions, 89 deletions
diff --git a/src/auto/injector.js b/src/auto/injector.js index b93446c0..8f8b78cf 100644 --- a/src/auto/injector.js +++ b/src/auto/injector.js @@ -253,83 +253,37 @@ function annotate(fn) { * * @description * - * Use `$provide` to register new providers with the `$injector`. The providers are the factories for the instance. - * The providers share the same name as the instance they create with `Provider` suffixed to them. - * - * A provider is an object with a `$get()` method. The injector calls the `$get` method to create a new instance of - * a service. The Provider can have additional methods which would allow for configuration of the provider. - * - * <pre> - * 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('Tracking', function() { - * var mocked; - * beforeEach(module(function($provide) { - * $provide.provider('tracking', TrackingProvider); - * mocked = {post: jasmine.createSpy('postSpy')}; - * $provide.value('$http',mocked); - * })); - * it('allows events to be tracked', inject(function(tracking) { - * expect(tracking.event('login')).toEqual(1); - * expect(tracking.event('login')).toEqual(2); - * })); - * - * it('posts to save', inject(function(tracking) { - * tracking.save(); - * expect(mocked.post.callCount).toEqual(1); - * })); - * }); - * </pre> - * - * 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. - * - * <pre> - * 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); - * </pre> - * - * `factory()` registers a function whose return value is the instance. Again, you can specify services that will be provided by the injector. - * - * <pre> - * 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); - * </pre> - * + * The {@link AUTO.$provide $provide} service has a number of methods for registering components with + * the {@link AUTO.$injector $injector}. Many of these functions are also exposed on {@link angular.Module}. + * + * 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. + * + * When you request a service, the {@link AUTO.$injector $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**. + * + * 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 {@link AUTO.$provide $provide} service has additional helper methods to register + * services without specifying a provider. + * + * * {@link AUTO.$provide#provider provider(provider)} - registers a **service provider** with the + * {@link AUTO.$injector $injector} + * * {@link AUTO.$provide#constant constant(obj)} - registers a value/object that can be accessed by + * providers and services. + * * {@link AUTO.$provide#value value(obj)} - registers a value/object that can only be accessed by + * services, not providers. + * * {@link AUTO.$provide#factory factory(fn)} - registers a service **factory function**, `fn`, that + * will be wrapped in a **service provider** object, whose `$get` property will contain the given + * factory function. + * * {@link AUTO.$provide#service service(class)} - registers a **constructor function**, `class` that + * will be wrapped in a **service provider** object, whose `$get` property will instantiate a new + * object using the given constructor function. + * + * See the individual methods for more information and examples. */ /** @@ -338,7 +292,18 @@ function annotate(fn) { * @methodOf AUTO.$provide * @description * - * Register a provider for a service. The providers can be retrieved and can have additional configuration methods. + * Register a **provider function** with the {@link AUTO.$injector $injector}. Provider functions are + * constructor functions, whose instances are responsible for "providing" a factory for a service. + * + * Service provider names start with the name of the service they provide followed by `Provider`. + * For example, the {@link ng.$log $log} service has a provider called {@link ng.$logProvider $logProvider}. + * + * 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 {@link ng.$logProvider $logProvider} has a method + * {@link ng.$logProvider#debugEnabled debugEnabled} + * which lets you specify whether the {@link ng.$log $log} service will log debug messages to the + * console or not. * * @param {string} name The name of the instance. NOTE: the provider will be available under `name + 'Provider'` key. * @param {(Object|function())} provider If the provider is: @@ -349,6 +314,70 @@ function annotate(fn) { * {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as `object`. * * @returns {Object} registered provider instance + + * @example + * + * The following example shows how to create a simple event tracking service and register it using + * {@link AUTO.$provide#provider $provide.provider()}. + * + * <pre> + * // Define the eventTracker provider + * function EventTrackerProvider() { + * var trackingUrl = '/track'; + * + * // A provider method for configuring where the tracked events should been saved + * this.setTrackingUrl = function(url) { + * trackingUrl = url; + * }; + * + * // The service factory function + * this.$get = ['$http', function($http) { + * var trackedEvents = {}; + * return { + * // Call this to track an event + * event: function(event) { + * var count = trackedEvents[event] || 0; + * count += 1; + * trackedEvents[event] = count; + * return count; + * }, + * // Call this to save the tracked events to the trackingUrl + * save: function() { + * $http.post(trackingUrl, trackedEvents); + * } + * }; + * }]; + * } + * + * describe('eventTracker', function() { + * var postSpy; + * + * beforeEach(module(function($provide) { + * // Register the eventTracker provider + * $provide.provider('eventTracker', EventTrackerProvider); + * })); + * + * beforeEach(module(function(eventTrackerProvider) { + * // Configure eventTracker provider + * eventTrackerProvider.setTrackingUrl('/custom-track'); + * })); + * + * it('tracks events', inject(function(eventTracker) { + * expect(eventTracker.event('login')).toEqual(1); + * expect(eventTracker.event('login')).toEqual(2); + * })); + * + * it('saves to the tracking url', inject(function(eventTracker, $http) { + * postSpy = spyOn($http, 'post'); + * eventTracker.event('login'); + * eventTracker.save(); + * expect(postSpy).toHaveBeenCalled(); + * expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track'); + * expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track'); + * expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 }); + * })); + * }); + * </pre> */ /** @@ -357,12 +386,32 @@ function annotate(fn) { * @methodOf AUTO.$provide * @description * - * A service whose instance is the return value of `$getFn`. Short hand for configuring services if only `$get` method is required. + * 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 {@link AUTO.$provide#factory $provide.factor(getFn)} if you do not need to configure + * your service in a provider. * * @param {string} name The name of the instance. * @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand for * `$provide.provider(name, {$get: $getFn})`. * @returns {Object} registered provider instance + * + * @example + * Here is an example of registering a service + * <pre> + * $provide.factory('ping', ['$http', function($http) { + * return function ping() { + * return $http.send('/ping'); + * }; + * }]); + * </pre> + * You would then inject and use this service like this: + * <pre> + * someModule.controller('Ctrl', ['ping', function(ping) { + * ping(); + * }]); + * </pre> */ @@ -372,11 +421,34 @@ function annotate(fn) { * @methodOf AUTO.$provide * @description * - * A service whose instance is created by invoking `constructor` with `new`. A short hand for registering services which use a constructor. + * 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 the service + * constructor function that will be used to instantiate the service instance. + * + * You should use {@link AUTO.$provide#service $provide.service(class)} if you define your service + * as a type/class. This is common when using {@link http://coffeescript.org CoffeeScript}. * * @param {string} name The name of the instance. * @param {Function} constructor A class (constructor function) that will be instantiated. * @returns {Object} registered provider instance + * + * @example + * Here is an example of registering a service using {@link AUTO.$provide#service $provide.service(class)} + * that is defined as a CoffeeScript class. + * <pre> + * class Ping + * constructor: (@$http)-> + * send: ()=> + * @$http.get('/ping') + * + * $provide.service('ping', ['$http', Ping]) + * </pre> + * You would then inject and use this service like this: + * <pre> + * someModule.controller 'Ctrl', ['ping', (ping)-> + * ping.send() + * ] + * </pre> */ @@ -386,11 +458,29 @@ function annotate(fn) { * @methodOf AUTO.$provide * @description * - * A short hand for configuring services if the `$get` method is a constant. + * Register a **value service** with the {@link AUTO.$injector $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**. * + * Value services are similar to constant services, except that they cannot be injected into a module + * configuration function (see {@link angular.Module#config}) but they can be overridden by an Angular + * {@link AUTO.$provide#decorator decorator}. + * * @param {string} name The name of the instance. * @param {*} value The value. * @returns {Object} registered provider instance + * + * @example + * Here are some examples of creating value services. + * <pre> + * $provide.constant('ADMIN_USER', 'admin'); + * + * $provide.constant('RoleLookup', { admin: 0, writer: 1, reader: 2 }); + * + * $provide.constant('halfOf', function(value) { + * return value / 2; + * }); + * </pre> */ @@ -400,13 +490,26 @@ function annotate(fn) { * @methodOf AUTO.$provide * @description * - * A constant value, but unlike {@link AUTO.$provide#value value} it can be injected - * into configuration function (other modules) and it is not interceptable by - * {@link AUTO.$provide#decorator decorator}. + * Register a **constant service**, such as a string, a number, an array, an object or a function, with + * the {@link AUTO.$injector $injector}. Unlike {@link AUTO.$provide#value value} it can be injected + * into a module configuration function (see {@link angular.Module#config}) and it cannot be + * overridden by an Angular {@link AUTO.$provide#decorator decorator}. * * @param {string} name The name of the constant. * @param {*} value The constant value. * @returns {Object} registered instance + * + * @example + * Here a some examples of creating constants: + * <pre> + * $provide.constant('SHARD_HEIGHT', 306); + * + * $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']); + * + * $provide.constant('double', function(value) { + * return value * 2; + * }); + * </pre> */ @@ -416,17 +519,29 @@ function annotate(fn) { * @methodOf AUTO.$provide * @description * - * Decoration of service, allows the decorator to intercept the service instance creation. The - * returned instance may be the original instance, or a new instance which delegates to the - * original instance. + * Register a **service decorator** with the {@link AUTO.$injector $injector}. A service decorator + * intercepts the creation of a service, allowing it to override or modify the behaviour of the + * service. The object returned by the decorator may be the original service, or a new service object + * which replaces or wraps and delegates to the original service. * * @param {string} name The name of the service to decorate. * @param {function()} decorator This function will be invoked when the service needs to be - * instantiated. The function is called using the {@link AUTO.$injector#invoke - * injector.invoke} method and is therefore fully injectable. Local injection arguments: + * instantiated and should return the decorated service instance. The function is called using + * the {@link AUTO.$injector#invoke injector.invoke} method and is therefore fully injectable. + * Local injection arguments: * * * `$delegate` - The original service instance, which can be monkey patched, configured, * decorated or delegated to. + * + * @example + * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting + * calls to {@link ng.$log#error $log.warn()}. + * <pre> + * $provider.decorator('$log', ['$delegate', function($delegate) { + * $delegate.warn = $delegate.error; + * return $delegate; + * }]); + * </pre> */ |
