aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPete Bacon Darwin2013-10-10 16:46:59 +0100
committerPete Bacon Darwin2013-10-10 18:22:52 +0100
commit770353df1956ab45bdbe45a4d5040caa40bf880f (patch)
treefb6ec18112ff9056f8a8daffefa939ac0c476616
parent85b7d24357a59876810d8b2494bd2bfbb920a5da (diff)
downloadangular.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.js293
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>
*/