Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 74ef7f1

Browse files
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
1 parent 3eb2fbf commit 74ef7f1

File tree

1 file changed

+204
-89
lines changed

1 file changed

+204
-89
lines changed

src/auto/injector.js

+204-89
Original file line numberDiff line numberDiff line change
@@ -269,83 +269,37 @@ function annotate(fn) {
269269
*
270270
* @description
271271
*
272-
* Use `$provide` to register new providers with the `$injector`. The providers are the factories for the instance.
273-
* The providers share the same name as the instance they create with `Provider` suffixed to them.
274-
*
275-
* A provider is an object with a `$get()` method. The injector calls the `$get` method to create a new instance of
276-
* a service. The Provider can have additional methods which would allow for configuration of the provider.
277-
*
278-
* <pre>
279-
* function TrackingProvider() {
280-
* this.$get = function($http) {
281-
* var observed = {};
282-
* return {
283-
* event: function(event) {
284-
* var current = observed[event];
285-
* return observed[event] = current ? current + 1 : 1;
286-
* },
287-
* save: function() {
288-
* $http.post("/track",observed);
289-
* }
290-
* };
291-
* };
292-
* }
293-
*
294-
* describe('Tracking', function() {
295-
* var mocked;
296-
* beforeEach(module(function($provide) {
297-
* $provide.provider('tracking', TrackingProvider);
298-
* mocked = {post: jasmine.createSpy('postSpy')};
299-
* $provide.value('$http',mocked);
300-
* }));
301-
* it('allows events to be tracked', inject(function(tracking) {
302-
* expect(tracking.event('login')).toEqual(1);
303-
* expect(tracking.event('login')).toEqual(2);
304-
* }));
305-
*
306-
* it('posts to save', inject(function(tracking) {
307-
* tracking.save();
308-
* expect(mocked.post.callCount).toEqual(1);
309-
* }));
310-
* });
311-
* </pre>
312-
*
313-
* There are also shorthand methods to define services that don't need to be configured beyond their `$get()` method.
314-
*
315-
* `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.
316-
*
317-
* <pre>
318-
* function TrackingProvider($http) {
319-
* var observed = {};
320-
* this.event = function(event) {
321-
* var current = observed[event];
322-
* return observed[event] = current ? current + 1 : 1;
323-
* };
324-
* this.save = function() {
325-
* $http.post("/track",observed);
326-
* };
327-
* }
328-
* $provider.service('tracking',TrackingProvider);
329-
* </pre>
330-
*
331-
* `factory()` registers a function whose return value is the instance. Again, you can specify services that will be provided by the injector.
332-
*
333-
* <pre>
334-
* function TrackingProvider($http) {
335-
* var observed = {};
336-
* return {
337-
* event: function(event) {
338-
* var current = observed[event];
339-
* return observed[event] = current ? current + 1 : 1;
340-
* },
341-
* save: function() {
342-
* $http.post("/track",observed);
343-
* }
344-
* };
345-
* }
346-
* $provider.factory('tracking',TrackingProvider);
347-
* </pre>
348-
*
272+
* The {@link AUTO.$provide $provide} service has a number of methods for registering components with
273+
* the {@link AUTO.$injector $injector}. Many of these functions are also exposed on {@link angular.Module}.
274+
*
275+
* An Angular **service** is a singleton object created by a **service factory**. These **service
276+
* factories** are functions which, in turn, are created by a **service provider**.
277+
* The **service providers** are constructor functions. When instantiated they must contain a property
278+
* called `$get`, which holds the **service factory** function.
279+
*
280+
* When you request a service, the {@link AUTO.$injector $injector} is responsible for finding the
281+
* correct **service provider**, instantiating it and then calling its `$get` **service factory**
282+
* function to get the instance of the **service**.
283+
*
284+
* Often services have no configuration options and there is no need to add methods to the service
285+
* provider. The provider will be no more than a constructor function with a `$get` property. For
286+
* these cases the {@link AUTO.$provide $provide} service has additional helper methods to register
287+
* services without specifying a provider.
288+
*
289+
* * {@link AUTO.$provide#provider provider(provider)} - registers a **service provider** with the
290+
* {@link AUTO.$injector $injector}
291+
* * {@link AUTO.$provide#constant constant(obj)} - registers a value/object that can be accessed by
292+
* providers and services.
293+
* * {@link AUTO.$provide#value value(obj)} - registers a value/object that can only be accessed by
294+
* services, not providers.
295+
* * {@link AUTO.$provide#factory factory(fn)} - registers a service **factory function**, `fn`, that
296+
* will be wrapped in a **service provider** object, whose `$get` property will contain the given
297+
* factory function.
298+
* * {@link AUTO.$provide#service service(class)} - registers a **constructor function**, `class` that
299+
* will be wrapped in a **service provider** object, whose `$get` property will instantiate a new
300+
* object using the given constructor function.
301+
*
302+
* See the individual methods for more information and examples.
349303
*/
350304

351305
/**
@@ -354,7 +308,18 @@ function annotate(fn) {
354308
* @methodOf AUTO.$provide
355309
* @description
356310
*
357-
* Register a provider for a service. The providers can be retrieved and can have additional configuration methods.
311+
* Register a **provider function** with the {@link AUTO.$injector $injector}. Provider functions are
312+
* constructor functions, whose instances are responsible for "providing" a factory for a service.
313+
*
314+
* Service provider names start with the name of the service they provide followed by `Provider`.
315+
* For example, the {@link ng.$log $log} service has a provider called {@link ng.$logProvider $logProvider}.
316+
*
317+
* Service provider objects can have additional methods which allow configuration of the provider and
318+
* its service. Importantly, you can configure what kind of service is created by the `$get` method,
319+
* or how that service will act. For example, the {@link ng.$logProvider $logProvider} has a method
320+
* {@link ng.$logProvider#debugEnabled debugEnabled}
321+
* which lets you specify whether the {@link ng.$log $log} service will log debug messages to the
322+
* console or not.
358323
*
359324
* @param {string} name The name of the instance. NOTE: the provider will be available under `name + 'Provider'` key.
360325
* @param {(Object|function())} provider If the provider is:
@@ -365,6 +330,70 @@ function annotate(fn) {
365330
* {@link AUTO.$injector#instantiate $injector.instantiate()}, then treated as `object`.
366331
*
367332
* @returns {Object} registered provider instance
333+
334+
* @example
335+
*
336+
* The following example shows how to create a simple event tracking service and register it using
337+
* {@link AUTO.$provide#provider $provide.provider()}.
338+
*
339+
* <pre>
340+
* // Define the eventTracker provider
341+
* function EventTrackerProvider() {
342+
* var trackingUrl = '/track';
343+
*
344+
* // A provider method for configuring where the tracked events should been saved
345+
* this.setTrackingUrl = function(url) {
346+
* trackingUrl = url;
347+
* };
348+
*
349+
* // The service factory function
350+
* this.$get = ['$http', function($http) {
351+
* var trackedEvents = {};
352+
* return {
353+
* // Call this to track an event
354+
* event: function(event) {
355+
* var count = trackedEvents[event] || 0;
356+
* count += 1;
357+
* trackedEvents[event] = count;
358+
* return count;
359+
* },
360+
* // Call this to save the tracked events to the trackingUrl
361+
* save: function() {
362+
* $http.post(trackingUrl, trackedEvents);
363+
* }
364+
* };
365+
* }];
366+
* }
367+
*
368+
* describe('eventTracker', function() {
369+
* var postSpy;
370+
*
371+
* beforeEach(module(function($provide) {
372+
* // Register the eventTracker provider
373+
* $provide.provider('eventTracker', EventTrackerProvider);
374+
* }));
375+
*
376+
* beforeEach(module(function(eventTrackerProvider) {
377+
* // Configure eventTracker provider
378+
* eventTrackerProvider.setTrackingUrl('/custom-track');
379+
* }));
380+
*
381+
* it('tracks events', inject(function(eventTracker) {
382+
* expect(eventTracker.event('login')).toEqual(1);
383+
* expect(eventTracker.event('login')).toEqual(2);
384+
* }));
385+
*
386+
* it('saves to the tracking url', inject(function(eventTracker, $http) {
387+
* postSpy = spyOn($http, 'post');
388+
* eventTracker.event('login');
389+
* eventTracker.save();
390+
* expect(postSpy).toHaveBeenCalled();
391+
* expect(postSpy.mostRecentCall.args[0]).not.toEqual('/track');
392+
* expect(postSpy.mostRecentCall.args[0]).toEqual('/custom-track');
393+
* expect(postSpy.mostRecentCall.args[1]).toEqual({ 'login': 1 });
394+
* }));
395+
* });
396+
* </pre>
368397
*/
369398

370399
/**
@@ -373,12 +402,32 @@ function annotate(fn) {
373402
* @methodOf AUTO.$provide
374403
* @description
375404
*
376-
* A service whose instance is the return value of `$getFn`. Short hand for configuring services if only `$get` method is required.
405+
* Register a **service factory**, which will be called to return the service instance.
406+
* This is short for registering a service where its provider consists of only a `$get` property,
407+
* which is the given service factory function.
408+
* You should use {@link AUTO.$provide#factory $provide.factor(getFn)} if you do not need to configure
409+
* your service in a provider.
377410
*
378411
* @param {string} name The name of the instance.
379412
* @param {function()} $getFn The $getFn for the instance creation. Internally this is a short hand for
380413
* `$provide.provider(name, {$get: $getFn})`.
381414
* @returns {Object} registered provider instance
415+
*
416+
* @example
417+
* Here is an example of registering a service
418+
* <pre>
419+
* $provide.factory('ping', ['$http', function($http) {
420+
* return function ping() {
421+
* return $http.send('/ping');
422+
* };
423+
* }]);
424+
* </pre>
425+
* You would then inject and use this service like this:
426+
* <pre>
427+
* someModule.controller('Ctrl', ['ping', function(ping) {
428+
* ping();
429+
* }]);
430+
* </pre>
382431
*/
383432

384433

@@ -388,11 +437,34 @@ function annotate(fn) {
388437
* @methodOf AUTO.$provide
389438
* @description
390439
*
391-
* A service whose instance is created by invoking `constructor` with `new`. A short hand for registering services which use a constructor.
440+
* Register a **service constructor**, which will be invoked with `new` to create the service instance.
441+
* This is short for registering a service where its provider's `$get` property is the service
442+
* constructor function that will be used to instantiate the service instance.
443+
*
444+
* You should use {@link AUTO.$provide#service $provide.service(class)} if you define your service
445+
* as a type/class. This is common when using {@link http://coffeescript.org CoffeeScript}.
392446
*
393447
* @param {string} name The name of the instance.
394448
* @param {Function} constructor A class (constructor function) that will be instantiated.
395449
* @returns {Object} registered provider instance
450+
*
451+
* @example
452+
* Here is an example of registering a service using {@link AUTO.$provide#service $provide.service(class)}
453+
* that is defined as a CoffeeScript class.
454+
* <pre>
455+
* class Ping
456+
* constructor: (@$http)->
457+
* send: ()=>
458+
* @$http.get('/ping')
459+
*
460+
* $provide.service('ping', ['$http', Ping])
461+
* </pre>
462+
* You would then inject and use this service like this:
463+
* <pre>
464+
* someModule.controller 'Ctrl', ['ping', (ping)->
465+
* ping.send()
466+
* ]
467+
* </pre>
396468
*/
397469

398470

@@ -402,11 +474,29 @@ function annotate(fn) {
402474
* @methodOf AUTO.$provide
403475
* @description
404476
*
405-
* A short hand for configuring services if the `$get` method is a constant.
477+
* Register a **value service** with the {@link AUTO.$injector $injector}, such as a string, a number,
478+
* an array, an object or a function. This is short for registering a service where its provider's
479+
* `$get` property is a factory function that takes no arguments and returns the **value service**.
406480
*
481+
* Value services are similar to constant services, except that they cannot be injected into a module
482+
* configuration function (see {@link angular.Module#config}) but they can be overridden by an Angular
483+
* {@link AUTO.$provide#decorator decorator}.
484+
*
407485
* @param {string} name The name of the instance.
408486
* @param {*} value The value.
409487
* @returns {Object} registered provider instance
488+
*
489+
* @example
490+
* Here are some examples of creating value services.
491+
* <pre>
492+
* $provide.constant('ADMIN_USER', 'admin');
493+
*
494+
* $provide.constant('RoleLookup', { admin: 0, writer: 1, reader: 2 });
495+
*
496+
* $provide.constant('halfOf', function(value) {
497+
* return value / 2;
498+
* });
499+
* </pre>
410500
*/
411501

412502

@@ -416,13 +506,26 @@ function annotate(fn) {
416506
* @methodOf AUTO.$provide
417507
* @description
418508
*
419-
* A constant value, but unlike {@link AUTO.$provide#value value} it can be injected
420-
* into configuration function (other modules) and it is not interceptable by
421-
* {@link AUTO.$provide#decorator decorator}.
509+
* Register a **constant service**, such as a string, a number, an array, an object or a function, with
510+
* the {@link AUTO.$injector $injector}. Unlike {@link AUTO.$provide#value value} it can be injected
511+
* into a module configuration function (see {@link angular.Module#config}) and it cannot be
512+
* overridden by an Angular {@link AUTO.$provide#decorator decorator}.
422513
*
423514
* @param {string} name The name of the constant.
424515
* @param {*} value The constant value.
425516
* @returns {Object} registered instance
517+
*
518+
* @example
519+
* Here a some examples of creating constants:
520+
* <pre>
521+
* $provide.constant('SHARD_HEIGHT', 306);
522+
*
523+
* $provide.constant('MY_COLOURS', ['red', 'blue', 'grey']);
524+
*
525+
* $provide.constant('double', function(value) {
526+
* return value * 2;
527+
* });
528+
* </pre>
426529
*/
427530

428531

@@ -432,17 +535,29 @@ function annotate(fn) {
432535
* @methodOf AUTO.$provide
433536
* @description
434537
*
435-
* Decoration of service, allows the decorator to intercept the service instance creation. The
436-
* returned instance may be the original instance, or a new instance which delegates to the
437-
* original instance.
538+
* Register a **service decorator** with the {@link AUTO.$injector $injector}. A service decorator
539+
* intercepts the creation of a service, allowing it to override or modify the behaviour of the
540+
* service. The object returned by the decorator may be the original service, or a new service object
541+
* which replaces or wraps and delegates to the original service.
438542
*
439543
* @param {string} name The name of the service to decorate.
440544
* @param {function()} decorator This function will be invoked when the service needs to be
441-
* instantiated. The function is called using the {@link AUTO.$injector#invoke
442-
* injector.invoke} method and is therefore fully injectable. Local injection arguments:
545+
* instantiated and should return the decorated service instance. The function is called using
546+
* the {@link AUTO.$injector#invoke injector.invoke} method and is therefore fully injectable.
547+
* Local injection arguments:
443548
*
444549
* * `$delegate` - The original service instance, which can be monkey patched, configured,
445550
* decorated or delegated to.
551+
*
552+
* @example
553+
* Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
554+
* calls to {@link ng.$log#error $log.warn()}.
555+
* <pre>
556+
* $provider.decorator('$log', ['$delegate', function($delegate) {
557+
* $delegate.warn = $delegate.error;
558+
* return $delegate;
559+
* }]);
560+
* </pre>
446561
*/
447562

448563

0 commit comments

Comments
 (0)