aboutsummaryrefslogtreecommitdiffstats
path: root/docs/content
diff options
context:
space:
mode:
authorBrian Ford2014-03-03 12:30:33 -0800
committerBrian Ford2014-03-03 12:30:33 -0800
commit220e7bf2d448fd80d98d5c2f3cfac3902433df8f (patch)
tree9b46c834e26a813705a6c39a418f7cef51f6e45b /docs/content
parent8d6eed21d219e459331a9f08fd46f8c67a9553da (diff)
downloadangular.js-220e7bf2d448fd80d98d5c2f3cfac3902433df8f.tar.bz2
docs(guide/services): rewrite services documentation
Diffstat (limited to 'docs/content')
-rw-r--r--docs/content/guide/$location.ngdoc (renamed from docs/content/guide/dev_guide.services.$location.ngdoc)4
-rw-r--r--docs/content/guide/dev_guide.services.creating_services.ngdoc106
-rw-r--r--docs/content/guide/dev_guide.services.injecting_controllers.ngdoc123
-rw-r--r--docs/content/guide/dev_guide.services.managing_dependencies.ngdoc113
-rw-r--r--docs/content/guide/dev_guide.services.ngdoc20
-rw-r--r--docs/content/guide/dev_guide.services.testing_services.ngdoc62
-rw-r--r--docs/content/guide/dev_guide.services.understanding_services.ngdoc60
-rw-r--r--docs/content/guide/services.ngdoc297
8 files changed, 299 insertions, 486 deletions
diff --git a/docs/content/guide/dev_guide.services.$location.ngdoc b/docs/content/guide/$location.ngdoc
index aae42ed2..a025aa47 100644
--- a/docs/content/guide/dev_guide.services.$location.ngdoc
+++ b/docs/content/guide/$location.ngdoc
@@ -1,5 +1,5 @@
@ngdoc overview
-@name Angular Services: Using $location
+@name Using $location
@description
# What does it do?
@@ -329,7 +329,7 @@ reload to the original link.
Example: `<a href="http://angularjs.org/">link</a>`
- Links starting with '/' that lead to a different base path when base is defined<br>
Example: `<a href="/not-my-base/link">link</a>`
-
+
When running Angular in the root of a domain, along side perhaps a normal application in the same
directory, the "otherwise" route handler will try to handle all the URLs, including ones that map
to static files.
diff --git a/docs/content/guide/dev_guide.services.creating_services.ngdoc b/docs/content/guide/dev_guide.services.creating_services.ngdoc
deleted file mode 100644
index d2d99157..00000000
--- a/docs/content/guide/dev_guide.services.creating_services.ngdoc
+++ /dev/null
@@ -1,106 +0,0 @@
-@ngdoc overview
-@name Angular Services: Creating Services
-@description
-
-While Angular offers several useful services, for any nontrivial application you'll find it useful
-to write your own custom services. To do this you begin by registering a service factory function
-with a module either via the {@link angular.module Module#factory api} or directly
-via the {@link auto.$provide $provide} api inside of module config function.
-
-All Angular services participate in {@link di dependency injection (DI)} by registering
-themselves with Angular's DI system (injector) under a `name` (id) as well as by declaring
-dependencies which need to be provided for the factory function of the registered service. The
-ability to swap dependencies for mocks/stubs/dummies in tests allows for services to be highly
-testable.
-
-
-# Registering Services
-
-To register a service, you must have a module that this service will be part of. Afterwards, you
-can register the service with the module either via the {@link angular.Module Module api} or
-by using the {@link auto.$provide $provide} service in the module configuration
-function. The following pseudo-code shows both approaches:
-
-Using the angular.Module api:
-
-```js
-var myModule = angular.module('myModule', []);
-myModule.factory('serviceId', function() {
- var shinyNewServiceInstance;
- //factory function body that constructs shinyNewServiceInstance
- return shinyNewServiceInstance;
-});
-```
-
-Using the $provide service:
-
-```js
-angular.module('myModule', [], function($provide) {
- $provide.factory('serviceId', function() {
- 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.
-
-
-# Dependencies
-
-Services can not only be depended upon, but can also have their own dependencies. These can be specified
-as arguments of the factory function. {@link di Read more} about dependency injection (DI)
-in Angular and the use of array notation and the $inject property to make DI annotation
-minification-proof.
-
-Following is an example of a very simple service. This service depends on the `$window` service
-(which is passed as a parameter to the factory function) and is just a function. The service simply
-stores all notifications; after the third one, the service displays all of the notifications by
-window alert.
-
-```js
-angular.module('myModule', [], function($provide) {
- $provide.factory('notify', ['$window', function(win) {
- var msgs = [];
- return function(msg) {
- msgs.push(msg);
- if (msgs.length == 3) {
- win.alert(msgs.join("\n"));
- msgs = [];
- }
- };
- }]);
-});
-```
-
-
-# Instantiating Angular Services
-
-All services in Angular are instantiated lazily. This means that a service will be created
-only when it is needed for instantiation of a service or an application component that depends on it.
-In other words, Angular won't instantiate services unless they are requested directly or
-indirectly by the application.
-
-
-# Services as singletons
-
-Lastly, it is important to realize that all Angular services are application singletons. This means
-that there is only one instance of a given service per injector. Since Angular is lethally allergic
-to global state, it is possible to create multiple injectors, each with its own instance of a
-given service, but that is rarely needed, except in tests where this property is crucially
-important.
-
-
-
-## Related Topics
-
-* {@link dev_guide.services.understanding_services Understanding Angular Services}
-* {@link dev_guide.services.managing_dependencies Managing Service Dependencies}
-* {@link dev_guide.services.injecting_controllers Injecting Services Into Controllers }
-* {@link dev_guide.services.testing_services Testing Angular Services}
-
-## Related API
-
-* {@link ng Angular Service API}
diff --git a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc
deleted file mode 100644
index ac58b4e4..00000000
--- a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc
+++ /dev/null
@@ -1,123 +0,0 @@
-@ngdoc overview
-@name Angular Services: Injecting Services Into Controllers
-@description
-
-Using services as dependencies for controllers is very similar to using services as dependencies
-for another service.
-
-Since JavaScript is a dynamic language, DI can't figure out which services to inject by static
-types (like in static typed languages). Therefore, you can specify the service name by using the
-`$inject` property, which is an array containing strings with names of services to be injected.
-The name must match the corresponding service ID registered with angular. The order of the service
-IDs matters: the order of the services in the array will be used when calling the factory function
-with injected parameters. The names of parameters in factory function don't matter, but by
-convention they match the service IDs, which has added benefits discussed below.
-
-```js
-function myController($loc, $log) {
- this.firstMethod = function() {
- // use $location service
- $loc.setHash();
- };
- this.secondMethod = function() {
- // use $log service
- $log.info('...');
- };
-}
-// which services to inject ?
-myController.$inject = ['$location', '$log'];
-```
-
-<example module="MyServiceModule">
- <file name="index.html">
- <div id="simple" ng-controller="myController">
- <p>Let's try this simple notify service, injected into the controller...</p>
- <input ng-init="message='test'" ng-model="message" >
- <button ng-click="callNotify(message);">NOTIFY</button>
- <p>(you have to click 3 times to see an alert)</p>
- </div>
- </file>
-
- <file name="script.js">
- angular.
- module('MyServiceModule', []).
- factory('notify', ['$window', function(win) {
- var msgs = [];
- return function(msg) {
- msgs.push(msg);
- if (msgs.length == 3) {
- win.alert(msgs.join("\n"));
- msgs = [];
- }
- };
- }]);
-
- function myController(scope, notifyService) {
- scope.callNotify = function(msg) {
- notifyService(msg);
- };
- }
-
- myController.$inject = ['$scope','notify'];
- </file>
-
- <file name="protractor.js" type="protractor">
- it('should test service', function() {
- expect(element(by.id('simple')).element(by.model('message')).getAttribute('value'))
- .toEqual('test');
- });
- </file>
-</example>
-
-## Implicit Dependency Injection
-
-A new feature of Angular DI allows it to determine the dependency from the name of the parameter.
-Let's rewrite the above example to show the use of this implicit dependency injection of
-`$window`, `$scope`, and our `notify` service:
-
-<example module="MyServiceModuleDI">
- <file name="index.html">
- <div id="implicit" ng-controller="myController">
- <p>Let's try the notify service, that is implicitly injected into the controller...</p>
- <input ng-init="message='test'" ng-model="message">
- <button ng-click="callNotify(message);">NOTIFY</button>
- <p>(you have to click 3 times to see an alert)</p>
- </div>
- </file>
-
- <file name="script.js">
- angular.
- module('MyServiceModuleDI', []).
- factory('notify', function($window) {
- var msgs = [];
- return function(msg) {
- msgs.push(msg);
- if (msgs.length == 3) {
- $window.alert(msgs.join("\n"));
- msgs = [];
- }
- };
- });
-
- function myController($scope, notify) {
- $scope.callNotify = function(msg) {
- notify(msg);
- };
- }
- </file>
-</example>
-
-However, if you plan to [minify](http://en.wikipedia.org/wiki/Minification_(programming)) your
-code, your variable names will get renamed in which case you will still need to explicitly specify
-dependencies with the `$inject` property.
-
-## Related Topics
-
-* {@link dev_guide.services.understanding_services Understanding Angular Services}
-* {@link dev_guide.services.creating_services Creating Angular Services}
-* {@link dev_guide.services.managing_dependencies Managing Service Dependencies}
-* {@link dev_guide.services.testing_services Testing Angular Services}
-
-## Related APIs
-
-* {@link ng Angular Service API}
diff --git a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc b/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc
deleted file mode 100644
index e9d8be8c..00000000
--- a/docs/content/guide/dev_guide.services.managing_dependencies.ngdoc
+++ /dev/null
@@ -1,113 +0,0 @@
-@ngdoc overview
-@name Angular Services: Managing Service Dependencies
-@description
-
-Angular allows services to declare other services as dependencies needed for construction of their
-instances.
-
-To declare dependencies, you specify them in the factory function signature and annotate the
-function with the inject annotations either using by setting the `$inject` property, as an array of
-string identifiers or using the array notation. Optionally the `$inject` property declaration can be
-dropped (see "Inferring `$inject`" but note that that is currently an experimental feature).
-
-Using the array notation:
-
-```js
-function myModuleCfgFn($provide) {
- $provide.factory('myService', ['dep1', 'dep2', function(dep1, dep2) {}]);
-}
-```
-
-
-Using the $inject property:
-
-```js
-function myModuleCfgFn($provide) {
- var myServiceFactory = function(dep1, dep2) {};
- myServiceFactory.$inject = ['dep1', 'dep2'];
- $provide.factory('myService', myServiceFactory);
-}
-```
-
-
-Using DI inference (incompatible with minifiers):
-
-```js
-function myModuleCfgFn($provide) {
- $provide.factory('myService', function(dep1, dep2) {});
-}
-```
-
-
-Here is an example of two services, one of which depends on the other and both
-of which depend on other services that are provided by the Angular framework:
-
-```js
-/**
- * batchLog service allows for messages to be queued in memory and flushed
- * to the console.log every 50 seconds.
- *
- * @param {*} message Message to be logged.
- */
- function batchLogModule($provide){
- $provide.factory('batchLog', ['$interval', '$log', function($interval, $log) {
- var messageQueue = [];
-
- function log() {
- if (messageQueue.length) {
- $log.log('batchLog messages: ', messageQueue);
- messageQueue = [];
- }
- }
-
- // start periodic checking
- $interval(log, 50000);
-
- return function(message) {
- messageQueue.push(message);
- }
- }]);
-
- /**
- * routeTemplateMonitor monitors each $route change and logs the current
- * template via the batchLog service.
- */
- $provide.factory('routeTemplateMonitor',
- ['$route', 'batchLog', '$rootScope',
- function($route, batchLog, $rootScope) {
- $rootScope.$on('$routeChangeSuccess', function() {
- batchLog($route.current ? $route.current.template : null);
- });
- }]);
- }
-
- // get the main service to kick off the application
- angular.injector([batchLogModule]).get('routeTemplateMonitor');
-```
-
-Things to notice in this example:
-
-* The `batchLog` service depends on the built-in {@link ng.$interval $interval} and
-{@link ng.$log $log} services, and allows messages to be logged into the
-`console.log` in batches.
-* The `routeTemplateMonitor` service depends on the built-in {@link ngRoute.$route
-$route} service as well as our custom `batchLog` service.
-* Both of our services use the factory function signature and array notation for inject annotations
-to declare their dependencies. It is important that the order of the string identifiers in the array
-is the same as the order of argument names in the signature of the factory function. Unless the
-dependencies are inferred from the function signature, it is this array with IDs and their order
-that the injector uses to determine which services and in which order to inject.
-
-
-## Related Topics
-
-* {@link dev_guide.services.understanding_services Understanding Angular Services}
-* {@link dev_guide.services.creating_services Creating Angular Services}
-* {@link dev_guide.services.injecting_controllers Injecting Services Into Controllers }
-* {@link dev_guide.services.testing_services Testing Angular Services}
-
-
-## Related API
-
-* {@link ./ng Angular Service API}
-* {@link angular.injector Angular Injector API}
diff --git a/docs/content/guide/dev_guide.services.ngdoc b/docs/content/guide/dev_guide.services.ngdoc
deleted file mode 100644
index 29eba46f..00000000
--- a/docs/content/guide/dev_guide.services.ngdoc
+++ /dev/null
@@ -1,20 +0,0 @@
-@ngdoc overview
-@name Angular Services
-@description
-
-Services are a feature that Angular brings to client-side web apps from the server side, where
-services have been commonly used for a long time. Services in Angular apps are substitutable
-objects that are wired together using {@link di dependency injection (DI)}.
-
-
-## Related Topics
-
-* {@link dev_guide.services.understanding_services Understanding Angular Services}
-* {@link dev_guide.services.creating_services Creating Angular Services}
-* {@link dev_guide.services.managing_dependencies Managing Service Dependencies}
-* {@link dev_guide.services.injecting_controllers Injecting Services Into Controllers}
-* {@link dev_guide.services.testing_services Testing Angular Services}
-
-## Related API
-
-* {@link ./ng Angular Service API}
diff --git a/docs/content/guide/dev_guide.services.testing_services.ngdoc b/docs/content/guide/dev_guide.services.testing_services.ngdoc
deleted file mode 100644
index 67a1635d..00000000
--- a/docs/content/guide/dev_guide.services.testing_services.ngdoc
+++ /dev/null
@@ -1,62 +0,0 @@
-@ngdoc overview
-@name Angular Services: Testing Angular Services
-@description
-
-The following is a unit test for the 'notify' service in the 'Dependencies' example in {@link
-dev_guide.services.creating_services Creating Angular Services}. The unit test example uses Jasmine
-spy (mock) instead of a real browser alert.
-
-```js
-var mock, notify;
-
-beforeEach(function() {
- mock = {alert: jasmine.createSpy()};
-
- module(function($provide) {
- $provide.value('$window', mock);
- });
-
- inject(function($injector) {
- notify = $injector.get('notify');
- });
-});
-
-it('should not alert first two notifications', function() {
- notify('one');
- notify('two');
-
- expect(mock.alert).not.toHaveBeenCalled();
-});
-
-it('should alert all after third notification', function() {
- notify('one');
- notify('two');
- notify('three');
-
- expect(mock.alert).toHaveBeenCalledWith("one\ntwo\nthree");
-});
-
-it('should clear messages after alert', function() {
- notify('one');
- notify('two');
- notify('third');
- notify('more');
- notify('two');
- notify('third');
-
- expect(mock.alert.callCount).toEqual(2);
- expect(mock.alert.mostRecentCall.args).toEqual(["more\ntwo\nthird"]);
-});
-```
-
-
-## Related Topics
-
-* {@link dev_guide.services.understanding_services Understanding Angular Services}
-* {@link dev_guide.services.creating_services Creating Angular Services}
-* {@link dev_guide.services.managing_dependencies Managing Service Dependencies}
-* {@link dev_guide.services.injecting_controllers Injecting Services Into Controllers}
-
-## Related API
-
-* {@link ./ng Angular Service API}
diff --git a/docs/content/guide/dev_guide.services.understanding_services.ngdoc b/docs/content/guide/dev_guide.services.understanding_services.ngdoc
deleted file mode 100644
index b1750884..00000000
--- a/docs/content/guide/dev_guide.services.understanding_services.ngdoc
+++ /dev/null
@@ -1,60 +0,0 @@
-@ngdoc overview
-@name Angular Services: Understanding Angular Services
-@description
-
-## What are Angular Services?
-
-Angular services are singletons objects or functions that carry out specific tasks common to web apps.
-Angular has a number of built in services, such as the {@link ng.$http $http service}, which
-provides access to the browser's `XMLHttpRequest` object for making requests to a server. Like other core
-Angular variables and identifiers, the built-in services always start with `$` (such as `$http` mentioned
-above). You can also create your own custom services.
-
-## Using a Service
-
-To use an Angular service, you identify 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. The Angular injector subsystem is in charge of service instantiation, resolution
-of dependencies, and provision of dependencies to components as requested.
-
-Angular injects dependencies using
-["constructor" injection](http://misko.hevery.com/2009/02/19/constructor-injection-vs-setter-injection/).
-The dependency is passed to the component's factory/constructor function. Because JavaScript is a dynamically
-typed language, Angular's dependency injection subsystem cannot use static types to identify service
-dependencies. For this reason a component must, explicitly, define its dependencies by using one of the
-{@link di injection annotation} methods. For example, by providing a `$inject` property:
-
- var MyController = function($location) { ... };
- MyController.$inject = ['$location'];
- myModule.controller('MyController', MyController);
-
-Or by providing an "inline" injection annotation:
-
- var myService = function($http) { ... };
- myModule.factory('myService', ['$http', myService]);
-
-## Defining a Service
-
-Application developers are free to define their own services by registering their name, and **service
-factory function**, in Angular modules.
-
-The purpose of the **service factory function** is to generate the single object, or function, that
-represents the service to the rest of the application. That object, or function, will then be
-injected into any component (controller, service, filter or directive) that specifies a dependency
-on the service.
-
-Angular factory functions are executed lazily. That is, they are only executed when needed
-to satisfy a dependency, and are then executed exactly once for each service. Everything that is
-dependent on this service gets a reference to the single instance generated by the service factory.
-
-## Related Topics
-
-* {@link guide/di About Angular Dependency Injection}
-* {@link guide/dev_guide.services.creating_services Creating Angular Services}
-* {@link guide/dev_guide.services.managing_dependencies Managing Service Dependencies}
-* {@link guide/dev_guide.services.testing_services Testing Angular Services}
-
-## Related API
-
-* {@link ./ng Angular Service API}
-* {@link angular.injector Injector API}
diff --git a/docs/content/guide/services.ngdoc b/docs/content/guide/services.ngdoc
new file mode 100644
index 00000000..d92be142
--- /dev/null
+++ b/docs/content/guide/services.ngdoc
@@ -0,0 +1,297 @@
+@ngdoc overview
+@name Services
+@description
+
+# Services
+
+Angular services are substitutable objects that are wired together using {@link di dependency
+injection (DI)}. You can use services to organize and share code across your app.
+
+Angular services are:
+
+* Lazily instantiated – Angular only instantiates a service when an application component depends
+ on it.
+* Singletons – Each component is dependent on a service gets a reference to the single instance
+ generated by the service factory.
+
+Angular offers several useful services (like {@link ng.$http `$http`}) but for most applications
+you'll also want to {@link services#creating-services create your own}.
+
+<div class="alert alert-info">
+**Note:** Like other core Angular identifiers built-in services always start with `$`
+(i.e. `$http`).
+</div>
+
+
+## Using a Service
+
+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 {@link di dependency injection}
+subsystem takes care of the rest.
+
+<example module="myServiceModule">
+ <file name="index.html">
+ <div id="simple" ng-controller="MyController">
+ <p>Let's try this simple notify service, injected into the controller...</p>
+ <input ng-init="message='test'" ng-model="message" >
+ <button ng-click="callNotify(message);">NOTIFY</button>
+ <p>(you have to click 3 times to see an alert)</p>
+ </div>
+ </file>
+
+ <file name="script.js">
+ angular.
+ module('myServiceModule', []).
+ controller('MyController', ['$scope','notify', function ($scope, notify) {
+ $scope.callNotify = function(msg) {
+ notify(msg);
+ };
+ }]).
+ factory('notify', ['$window', function(win) {
+ var msgs = [];
+ return function(msg) {
+ msgs.push(msg);
+ if (msgs.length == 3) {
+ win.alert(msgs.join("\n"));
+ msgs = [];
+ }
+ };
+ }]);
+ </file>
+
+ <file name="protractor.js" type="protractor">
+ it('should test service', function() {
+ expect(element(by.id('simple')).element(by.model('message')).getAttribute('value'))
+ .toEqual('test');
+ });
+ </file>
+</example>
+
+<div class="alert alert-info">
+**Note:** Angular uses
+[**constructor injection**](http://misko.hevery.com/2009/02/19/constructor-injection-vs-setter-injection/).
+</div>
+
+### Explicit Dependency Injection
+
+A component should explicitly define its dependencies using one of the {@link di injection
+annotation} methods:
+
+1. Inline array injection annotation (preferred):
+ ```js
+ myModule.controller('MyController', ['$location', function($location) { ... }]);
+ ```
+
+2. `$inject` property:
+ ```js
+ var MyController = function($location) { ... };
+ MyController.$inject = ['$location'];
+ myModule.controller('MyController', MyController);
+ ```
+
+<div class="alert alert-success">
+**Best Practice:** Use the array annotation shown above.
+</div>
+
+### Implicit Dependency Injection
+
+Even if you don't annotate your dependencies, Angular's DI can determine the dependency from the
+name of the parameter. Let's rewrite the above example to show the use of this implicit dependency
+injection of `$window`, `$scope`, and our `notify` service:
+
+<example module="myServiceModuleDI">
+ <file name="index.html">
+ <div id="implicit" ng-controller="MyController">
+ <p>Let's try the notify service, that is implicitly injected into the controller...</p>
+ <input ng-init="message='test'" ng-model="message">
+ <button ng-click="callNotify(message);">NOTIFY</button>
+ <p>(you have to click 3 times to see an alert)</p>
+ </div>
+ </file>
+
+ <file name="script.js">
+ angular.module('myServiceModuleDI', []).
+ factory('notify', function($window) {
+ var msgs = [];
+ return function(msg) {
+ msgs.push(msg);
+ if (msgs.length == 3) {
+ $window.alert(msgs.join("\n"));
+ msgs = [];
+ }
+ };
+ }).
+ controller('MyController', function($scope, notify) {
+ $scope.callNotify = function(msg) {
+ notify(msg);
+ };
+ });
+ </file>
+</example>
+
+<div class="alert alert-error">
+**Careful:** If you plan to [minify](http://en.wikipedia.org/wiki/Minification_(programming) your code,
+your variable names will get renamed unless you use one of the annotation techniques above.
+</div>
+
+
+## Creating Services
+
+Application developers are free to define their own services by registering the service's name and
+**service factory function**, with an Angular module.
+
+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.
+
+### Registering Services
+
+Services are registered to modules via the {@link angular.Module Module API}.
+Typically you use the {@link angular.module Module#factory} API to register a service:
+
+```javascript
+var myModule = angular.module('myModule', []);
+myModule.factory('serviceId', function() {
+ 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.
+
+### Dependencies
+
+Services can have their own dependencies. Just like declaring dependencies in a controller, you
+declare dependencies by specifying them in the service's factory function signature.
+
+The example module below has two services, each with various dependencies:
+
+```js
+var batchModule = angular.module('batchModule', []);
+
+/**
+ * The `batchLog` service allows for messages to be queued in memory and flushed
+ * to the console.log every 50 seconds.
+ *
+ * @param {*} message Message to be logged.
+ */
+batchModule.factory('batchLog', ['$interval', '$log', function($interval, $log) {
+ var messageQueue = [];
+
+ function log() {
+ if (messageQueue.length) {
+ $log.log('batchLog messages: ', messageQueue);
+ messageQueue = [];
+ }
+ }
+
+ // start periodic checking
+ $interval(log, 50000);
+
+ return function(message) {
+ messageQueue.push(message);
+ }
+}]);
+
+/**
+ * `routeTemplateMonitor` monitors each `$route` change and logs the current
+ * template via the `batchLog` service.
+ */
+batchModule.factory('routeTemplateMonitor', ['$route', 'batchLog', '$rootScope',
+ function($route, batchLog, $rootScope) {
+ $rootScope.$on('$routeChangeSuccess', function() {
+ batchLog($route.current ? $route.current.template : null);
+ });
+ }]);
+
+```
+
+In the example, note that:
+
+* The `batchLog` service depends on the built-in {@link ng.$interval `$interval`} and
+ {@link ng.$log `$log`} services.
+* The `routeTemplateMonitor` service depends on the built-in {@link ngRoute.$route `$route`}
+ service and our custom `batchLog` service.
+* Both services use the and array notation to declare their dependencies.
+* That the order of identifiers in the array is the same as the order of argument
+ names in the factory function.
+
+### Registering a Service with `$provide`
+
+You can also register services via the {@link auto.$provide `$provide`} service inside of a
+module's `config` function:
+
+```javascript
+angular.module('myModule', []).config(function($provide) {
+ $provide.factory('serviceId', function() {
+ var shinyNewServiceInstance;
+ //factory function body that constructs shinyNewServiceInstance
+ return shinyNewServiceInstance;
+ });
+});
+```
+
+This is technique is often used in unit tests to mock out a service's dependencies.
+
+
+## Unit Testing
+
+The following is a unit test for the `notify` service from the {@link services#creating-services
+Creating Angular Services} example above. The unit test example uses a Jasmine spy (mock) instead
+of a real browser alert.
+
+```js
+var mock, notify;
+
+beforeEach(function() {
+ mock = {alert: jasmine.createSpy()};
+
+ module(function($provide) {
+ $provide.value('$window', mock);
+ });
+
+ inject(function($injector) {
+ notify = $injector.get('notify');
+ });
+});
+
+it('should not alert first two notifications', function() {
+ notify('one');
+ notify('two');
+
+ expect(mock.alert).not.toHaveBeenCalled();
+});
+
+it('should alert all after third notification', function() {
+ notify('one');
+ notify('two');
+ notify('three');
+
+ expect(mock.alert).toHaveBeenCalledWith("one\ntwo\nthree");
+});
+
+it('should clear messages after alert', function() {
+ notify('one');
+ notify('two');
+ notify('third');
+ notify('more');
+ notify('two');
+ notify('third');
+
+ expect(mock.alert.callCount).toEqual(2);
+ expect(mock.alert.mostRecentCall.args).toEqual(["more\ntwo\nthird"]);
+});
+```
+
+
+## Related Topics
+
+* {@link guide/di Dependency Injection in AngularJS}
+
+## Related API
+
+* {@link ./ng Angular Service API}
+* {@link angular.injector Injector API}