From 220e7bf2d448fd80d98d5c2f3cfac3902433df8f Mon Sep 17 00:00:00 2001
From: Brian Ford
Date: Mon, 3 Mar 2014 12:30:33 -0800
Subject: docs(guide/services): rewrite services documentation
---
docs/content/guide/$location.ngdoc | 662 +++++++++++++++++++++
.../guide/dev_guide.services.$location.ngdoc | 662 ---------------------
.../dev_guide.services.creating_services.ngdoc | 106 ----
.../dev_guide.services.injecting_controllers.ngdoc | 123 ----
.../dev_guide.services.managing_dependencies.ngdoc | 113 ----
docs/content/guide/dev_guide.services.ngdoc | 20 -
.../dev_guide.services.testing_services.ngdoc | 62 --
...dev_guide.services.understanding_services.ngdoc | 60 --
docs/content/guide/services.ngdoc | 297 +++++++++
9 files changed, 959 insertions(+), 1146 deletions(-)
create mode 100644 docs/content/guide/$location.ngdoc
delete mode 100644 docs/content/guide/dev_guide.services.$location.ngdoc
delete mode 100644 docs/content/guide/dev_guide.services.creating_services.ngdoc
delete mode 100644 docs/content/guide/dev_guide.services.injecting_controllers.ngdoc
delete mode 100644 docs/content/guide/dev_guide.services.managing_dependencies.ngdoc
delete mode 100644 docs/content/guide/dev_guide.services.ngdoc
delete mode 100644 docs/content/guide/dev_guide.services.testing_services.ngdoc
delete mode 100644 docs/content/guide/dev_guide.services.understanding_services.ngdoc
create mode 100644 docs/content/guide/services.ngdoc
(limited to 'docs/content')
diff --git a/docs/content/guide/$location.ngdoc b/docs/content/guide/$location.ngdoc
new file mode 100644
index 00000000..a025aa47
--- /dev/null
+++ b/docs/content/guide/$location.ngdoc
@@ -0,0 +1,662 @@
+@ngdoc overview
+@name Using $location
+@description
+
+# What does it do?
+
+The `$location` service parses the URL in the browser address bar (based on the [window.location](https://developer.mozilla.org/en/window.location)) and makes the URL available to
+your application. Changes to the URL in the address bar are reflected into $location service and
+changes to $location are reflected into the browser address bar.
+
+**The $location service:**
+
+- Exposes the current URL in the browser address bar, so you can
+ - Watch and observe the URL.
+ - Change the URL.
+- Maintains synchronization between itself and the browser's URL when the user
+ - Changes the address in the browser's address bar.
+ - Clicks the back or forward button in the browser (or clicks a History link).
+ - Clicks on a link in the page.
+- Represents the URL object as a set of methods (protocol, host, port, path, search, hash).
+
+
+## Comparing $location to window.location
+
+
+
+
+
+
+
window.location
+
$location service
+
+
+
+
+
+
+
purpose
+
allow read/write access to the current browser location
+
same
+
+
+
+
API
+
exposes "raw" object with properties that can be directly modified
+
exposes jQuery-style getters and setters
+
+
+
+
integration with angular application life-cycle
+
none
+
knows about all internal life-cycle phases, integrates with $watch, ...
+
+
+
+
seamless integration with HTML5 API
+
no
+
yes (with a fallback for legacy browsers)
+
+
+
+
aware of docroot/context from which the application is loaded
+
no - window.location.path returns "/docroot/actual/path"
+
yes - $location.path() returns "/actual/path"
+
+
+
+
+
+## When should I use $location?
+Any time your application needs to react to a change in the current URL or if you want to change
+the current URL in the browser.
+
+## What does it not do?
+It does not cause a full page reload when the browser URL is changed. To reload the page after
+changing the URL, use the lower-level API, `$window.location.href`.
+
+# General overview of the API
+
+The `$location` service can behave differently, depending on the configuration that was provided to
+it when it was instantiated. The default configuration is suitable for many applications, for
+others customizing the configuration can enable new features.
+
+Once the `$location` service is instantiated, you can interact with it via jQuery-style getter and
+setter methods that allow you to get or change the current URL in the browser.
+
+## $location service configuration
+
+To configure the `$location` service, retrieve the
+{@link ng.$locationProvider $locationProvider} and set the parameters as follows:
+
+
+- **html5Mode(mode)**: {boolean}
+ `true` - see HTML5 mode
+ `false` - see Hashbang mode
+ default: `false`
+
+- **hashPrefix(prefix)**: {string}
+ prefix used for Hashbang URLs (used in Hashbang mode or in legacy browser in Html5 mode)
+ default: `""`
+
+### Example configuration
+```js
+$locationProvider.html5Mode(true).hashPrefix('!');
+```
+
+## Getter and setter methods
+
+`$location` service provides getter methods for read-only parts of the URL (absUrl, protocol, host,
+port) and getter / setter methods for url, path, search, hash:
+```js
+// get the current path
+$location.path();
+
+// change the path
+$location.path('/newValue')
+```
+
+All of the setter methods return the same `$location` object to allow chaining. For example, to
+change multiple segments in one go, chain setters like this:
+
+```js
+$location.path('/newValue').search({key: value});
+```
+
+## Replace method
+
+There is a special `replace` method which can be used to tell the $location service that the next
+time the $location service is synced with the browser, the last history record should be replaced
+instead of creating a new one. This is useful when you want to implement redirection, which would
+otherwise break the back button (navigating back would retrigger the redirection). To change the
+current URL without creating a new browser history record you can call:
+
+```js
+ $location.path('/someNewPath');
+ $location.replace();
+ // or you can chain these as: $location.path('/someNewPath').replace();
+```
+
+Note that the setters don't update `window.location` immediately. Instead, the `$location` service is
+aware of the {@link ng.$rootScope.Scope scope} life-cycle and coalesces multiple `$location`
+mutations into one "commit" to the `window.location` object during the scope `$digest` phase. Since
+multiple changes to the $location's state will be pushed to the browser as a single change, it's
+enough to call the `replace()` method just once to make the entire "commit" a replace operation
+rather than an addition to the browser history. Once the browser is updated, the $location service
+resets the flag set by `replace()` method and future mutations will create new history records,
+unless `replace()` is called again.
+
+### Setters and character encoding
+You can pass special characters to `$location` service and it will encode them according to rules
+specified in [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt). When you access the methods:
+
+- All values that are passed to `$location` setter methods, `path()`, `search()`, `hash()`, are
+encoded.
+- Getters (calls to methods without parameters) return decoded values for the following methods
+`path()`, `search()`, `hash()`.
+- When you call the `absUrl()` method, the returned value is a full url with its segments encoded.
+- When you call the `url()` method, the returned value is path, search and hash, in the form
+`/path?search=a&b=c#hash`. The segments are encoded as well.
+
+
+# Hashbang and HTML5 Modes
+
+`$location` service has two configuration modes which control the format of the URL in the browser
+address bar: **Hashbang mode** (the default) and the **HTML5 mode** which is based on using the
+HTML5 [History API](http://www.w3.org/TR/html5/history.html). Applications use the same API in
+both modes and the `$location` service will work with appropriate URL segments and browser APIs to
+facilitate the browser URL change and history management.
+
+
+
+
+
+
+
+
+
Hashbang mode
+
HTML5 mode
+
+
+
+
+
+
+
configuration
+
the default
+
{ html5Mode: true }
+
+
+
+
URL format
+
hashbang URLs in all browsers
+
regular URLs in modern browser, hashbang URLs in old browser
+
+
+
+
<a href=""> link rewriting
+
no
+
yes
+
+
+
+
requires server-side configuration
+
no
+
yes
+
+
+
+
+## Hashbang mode (default mode)
+
+In this mode, `$location` uses Hashbang URLs in all browsers.
+
+### Example
+
+```js
+it('should show example', inject(
+ function($locationProvider) {
+ $locationProvider.html5Mode(false);
+ $locationProvider.hashPrefix('!');
+ },
+ function($location) {
+ // open http://example.com/base/index.html#!/a
+ $location.absUrl() == 'http://example.com/base/index.html#!/a'
+ $location.path() == '/a'
+
+ $location.path('/foo')
+ $location.absUrl() == 'http://example.com/base/index.html#!/foo'
+
+ $location.search() == {}
+ $location.search({a: 'b', c: true});
+ $location.absUrl() == 'http://example.com/base/index.html#!/foo?a=b&c'
+
+ $location.path('/new').search('x=y');
+ $location.absUrl() == 'http://example.com/base/index.html#!/new?x=y'
+ }
+));
+```
+
+### Crawling your app
+
+To allow indexing of your AJAX application, you have to add special meta tag in the head section of
+your document:
+
+```html
+
+```
+
+This will cause crawler bot to request links with `_escaped_fragment_` param so that your server
+can recognize the crawler and serve a HTML snapshots. For more information about this technique,
+see [Making AJAX Applications
+Crawlable](http://code.google.com/web/ajaxcrawling/docs/specification.html).
+
+## HTML5 mode
+
+In HTML5 mode, the `$location` service getters and setters interact with the browser URL address
+through the HTML5 history API, which allows for use of regular URL path and search segments,
+instead of their hashbang equivalents. If the HTML5 History API is not supported by a browser, the
+`$location` service will fall back to using the hashbang URLs automatically. This frees you from
+having to worry about whether the browser displaying your app supports the history API or not; the
+`$location` service transparently uses the best available option.
+
+- Opening a regular URL in a legacy browser -> redirects to a hashbang URL
+- Opening hashbang URL in a modern browser -> rewrites to a regular URL
+
+### Example
+
+```js
+it('should show example', inject(
+ function($locationProvider) {
+ $locationProvider.html5Mode(true);
+ $locationProvider.hashPrefix('!');
+ },
+ function($location) {
+ // in browser with HTML5 history support:
+ // open http://example.com/#!/a -> rewrite to http://example.com/a
+ // (replacing the http://example.com/#!/a history record)
+ $location.path() == '/a'
+
+ $location.path('/foo');
+ $location.absUrl() == 'http://example.com/foo'
+
+ $location.search() == {}
+ $location.search({a: 'b', c: true});
+ $location.absUrl() == 'http://example.com/foo?a=b&c'
+
+ $location.path('/new').search('x=y');
+ $location.url() == 'new?x=y'
+ $location.absUrl() == 'http://example.com/new?x=y'
+
+ // in browser without html5 history support:
+ // open http://example.com/new?x=y -> redirect to http://example.com/#!/new?x=y
+ // (again replacing the http://example.com/new?x=y history item)
+ $location.path() == '/new'
+ $location.search() == {x: 'y'}
+
+ $location.path('/foo/bar');
+ $location.path() == '/foo/bar'
+ $location.url() == '/foo/bar?x=y'
+ $location.absUrl() == 'http://example.com/#!/foo/bar?x=y'
+ }
+));
+```
+
+### Fallback for legacy browsers
+
+For browsers that support the HTML5 history API, `$location` uses the HTML5 history API to write
+path and search. If the history API is not supported by a browser, `$location` supplies a Hasbang
+URL. This frees you from having to worry about whether the browser viewing your app supports the
+history API or not; the `$location` service makes this transparent to you.
+
+### Html link rewriting
+
+When you use HTML5 history API mode, you will need different links in different browsers, but all you
+have to do is specify regular URL links, such as: `link`
+
+When a user clicks on this link,
+
+- In a legacy browser, the URL changes to `/index.html#!/some?foo=bar`
+- In a modern browser, the URL changes to `/some?foo=bar`
+
+
+In cases like the following, links are not rewritten; instead, the browser will perform a full page
+reload to the original link.
+
+- Links that contain `target` element
+ Example: `link`
+- Absolute links that go to a different domain
+ Example: `link`
+- Links starting with '/' that lead to a different base path when base is defined
+ Example: `link`
+
+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.
+
+To prevent this, you can set your base href for the app to `` and then prefix links
+to URLs that should be handled with `.`. Now, links to locations, which are not to be routed by Angular,
+are not prefixed with `.` and will not be intercepted by the `otherwise` rule in your `$routeProvider`.
+
+
+### Server side
+
+Using this mode requires URL rewriting on server side, basically you have to rewrite all your links
+to entry point of your application (e.g. index.html)
+
+### Crawling your app
+
+If you want your AJAX application to be indexed by web crawlers, you will need to add the following
+meta tag to the HEAD section of your document:
+
+```html
+
+```
+
+This statement causes a crawler to request links with an empty `_escaped_fragment_` parameter so that
+your server can recognize the crawler and serve it HTML snapshots. For more information about this
+technique, see [Making AJAX
+Applications Crawlable](http://code.google.com/web/ajaxcrawling/docs/specification.html).
+
+### Relative links
+
+Be sure to check all relative links, images, scripts etc. You must either specify the url base in
+the head of your main html file (``) or you must use absolute urls
+(starting with `/`) everywhere because relative urls will be resolved to absolute urls using the
+initial absolute url of the document, which is often different from the root of the application.
+
+Running Angular apps with the History API enabled from document root is strongly encouraged as it
+takes care of all relative link issues.
+
+### Sending links among different browsers
+
+Because of rewriting capability in HTML5 mode, your users will be able to open regular url links in
+legacy browsers and hashbang links in modern browser:
+
+- Modern browser will rewrite hashbang URLs to regular URLs.
+- Older browsers will redirect regular URLs to hashbang URLs.
+
+### Example
+
+Here you can see two `$location` instances, both in **Html5 mode**, but on different browsers, so
+that you can see the differences. These `$location` services are connected to a fake browsers. Each
+input represents address bar of the browser.
+
+Note that when you type hashbang url into first browser (or vice versa) it doesn't rewrite /
+redirect to regular / hashbang url, as this conversion happens only during parsing the initial URL
+= on page reload.
+
+In this examples we use ``
+
+
+
+
+
+
+ function FakeBrowser(initUrl, baseHref) {
+ this.onUrlChange = function(fn) {
+ this.urlChange = fn;
+ };
+
+ this.url = function() {
+ return initUrl;
+ };
+
+ this.defer = function(fn, delay) {
+ setTimeout(function() { fn(); }, delay || 0);
+ };
+
+ this.baseHref = function() {
+ return baseHref;
+ };
+
+ this.notifyWhenOutstandingRequests = angular.noop;
+ }
+
+ var browsers = {
+ html5: new FakeBrowser('http://www.example.com/base/path?a=b#h', '/base/index.html'),
+ hashbang: new FakeBrowser('http://www.example.com/base/index.html#!/path?a=b#h', '/base/index.html')
+ };
+
+ function Html5Cntl($scope, $location) {
+ $scope.$location = $location;
+ }
+
+ function HashbangCntl($scope, $location) {
+ $scope.$location = $location;
+ }
+
+ function initEnv(name) {
+ var root = angular.element(document.getElementById(name + '-mode'));
+ // We must kill a link to the injector for this element otherwise angular will
+ // complain that it has been bootstrapped already.
+ root.data('$injector', null);
+ angular.bootstrap(root, [function($compileProvider, $locationProvider, $provide){
+ $locationProvider.html5Mode(true).hashPrefix('!');
+
+ $provide.value('$browser', browsers[name]);
+ $provide.value('$sniffer', {history: name == 'html5'});
+
+ $compileProvider.directive('ngAddressBar', function() {
+ return function(scope, elm, attrs) {
+ var browser = browsers[attrs.browser],
+ input = angular.element('').val(browser.url()),
+ delay;
+
+ input.on('keypress keyup keydown', function() {
+ if (!delay) {
+ delay = setTimeout(fireUrlChange, 250);
+ }
+ });
+
+ browser.url = function(url) {
+ return input.val(url);
+ };
+
+ elm.append('Address: ').append(input);
+
+ function fireUrlChange() {
+ delay = null;
+ browser.urlChange(input.val());
+ }
+ };
+ });
+ }]);
+ root.on('click', function(e) {
+ e.stopPropagation();
+ });
+ }
+
+ initEnv('html5');
+ initEnv('hashbang');
+
+
+
+
+# Caveats
+
+## Page reload navigation
+
+The `$location` service allows you to change only the URL; it does not allow you to reload the
+page. When you need to change the URL and reload the page or navigate to a different page, please
+use a lower level API, {@link ng.$window $window.location.href}.
+
+## Using $location outside of the scope life-cycle
+
+`$location` knows about Angular's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
+the browser it updates the `$location` and calls `$apply` so that all $watchers / $observers are
+notified.
+When you change the `$location` inside the `$digest` phase everything is ok; `$location` will
+propagate this change into browser and will notify all the $watchers / $observers.
+When you want to change the `$location` from outside Angular (for example, through a DOM Event or
+during testing) - you must call `$apply` to propagate the changes.
+
+## $location.path() and ! or / prefixes
+
+A path should always begin with forward slash (`/`); the `$location.path()` setter will add the
+forward slash if it is missing.
+
+Note that the `!` prefix in the hashbang mode is not part of `$location.path()`; it is actually
+hashPrefix.
+
+
+# Testing with the $location service
+
+When using `$location` service during testing, you are outside of the angular's {@link
+ng.$rootScope.Scope scope} life-cycle. This means it's your responsibility to call `scope.$apply()`.
+
+```js
+describe('serviceUnderTest', function() {
+ beforeEach(module(function($provide) {
+ $provide.factory('serviceUnderTest', function($location){
+ // whatever it does...
+ });
+ });
+
+ it('should...', inject(function($location, $rootScope, serviceUnderTest) {
+ $location.path('/new/path');
+ $rootScope.$apply();
+
+ // test whatever the service should do...
+
+ }));
+});
+```
+
+
+# Migrating from earlier AngularJS releases
+
+In earlier releases of Angular, `$location` used `hashPath` or `hashSearch` to process path and
+search methods. With this release, the `$location` service processes path and search methods and
+then uses the information it obtains to compose hashbang URLs (such as
+`http://server.com/#!/path?search=a`), when necessary.
+
+## Changes to your code
+
+
+
+
+
Navigation inside the app
+
Change to
+
+
+
+
+
+
$location.href = value $location.hash = value $location.update(value) $location.updateHash(value)
+
$location.path(path).search(search)
+
+
+
+
$location.hashPath = path
+
$location.path(path)
+
+
+
+
$location.hashSearch = search
+
$location.search(search)
+
+
+
+
Navigation outside the app
+
Use lower level API
+
+
+
+
$location.href = value $location.update(value)
+
$window.location.href = value
+
+
+
+
$location[protocol | host | port | path | search]
+
$window.location[protocol | host | port | path | search]
+
+## Two-way binding to $location
+
+The Angular's compiler currently does not support two-way binding for methods (see [issue](https://github.com/angular/angular.js/issues/404)). If you should require two-way binding
+to the $location object (using {@link input[text] ngModel} directive on an input
+field), you will need to specify an extra model property (e.g. `locationPath`) with two watchers
+which push $location updates in both directions. For example:
+
+
+
+
+
+
+
+function LocationController($scope, $location) {
+ $scope.$watch('locationPath', function(path) {
+ $location.path(path);
+ });
+ $scope.$watch(function() {
+ return $location.path();
+ }, function(path) {
+ $scope.locationPath = path;
+ });
+}
+
+
+
+# Related API
+
+* {@link ng.$location $location API}
+
+
+
diff --git a/docs/content/guide/dev_guide.services.$location.ngdoc b/docs/content/guide/dev_guide.services.$location.ngdoc
deleted file mode 100644
index aae42ed2..00000000
--- a/docs/content/guide/dev_guide.services.$location.ngdoc
+++ /dev/null
@@ -1,662 +0,0 @@
-@ngdoc overview
-@name Angular Services: Using $location
-@description
-
-# What does it do?
-
-The `$location` service parses the URL in the browser address bar (based on the [window.location](https://developer.mozilla.org/en/window.location)) and makes the URL available to
-your application. Changes to the URL in the address bar are reflected into $location service and
-changes to $location are reflected into the browser address bar.
-
-**The $location service:**
-
-- Exposes the current URL in the browser address bar, so you can
- - Watch and observe the URL.
- - Change the URL.
-- Maintains synchronization between itself and the browser's URL when the user
- - Changes the address in the browser's address bar.
- - Clicks the back or forward button in the browser (or clicks a History link).
- - Clicks on a link in the page.
-- Represents the URL object as a set of methods (protocol, host, port, path, search, hash).
-
-
-## Comparing $location to window.location
-
-
-
-
-
-
-
window.location
-
$location service
-
-
-
-
-
-
-
purpose
-
allow read/write access to the current browser location
-
same
-
-
-
-
API
-
exposes "raw" object with properties that can be directly modified
-
exposes jQuery-style getters and setters
-
-
-
-
integration with angular application life-cycle
-
none
-
knows about all internal life-cycle phases, integrates with $watch, ...
-
-
-
-
seamless integration with HTML5 API
-
no
-
yes (with a fallback for legacy browsers)
-
-
-
-
aware of docroot/context from which the application is loaded
-
no - window.location.path returns "/docroot/actual/path"
-
yes - $location.path() returns "/actual/path"
-
-
-
-
-
-## When should I use $location?
-Any time your application needs to react to a change in the current URL or if you want to change
-the current URL in the browser.
-
-## What does it not do?
-It does not cause a full page reload when the browser URL is changed. To reload the page after
-changing the URL, use the lower-level API, `$window.location.href`.
-
-# General overview of the API
-
-The `$location` service can behave differently, depending on the configuration that was provided to
-it when it was instantiated. The default configuration is suitable for many applications, for
-others customizing the configuration can enable new features.
-
-Once the `$location` service is instantiated, you can interact with it via jQuery-style getter and
-setter methods that allow you to get or change the current URL in the browser.
-
-## $location service configuration
-
-To configure the `$location` service, retrieve the
-{@link ng.$locationProvider $locationProvider} and set the parameters as follows:
-
-
-- **html5Mode(mode)**: {boolean}
- `true` - see HTML5 mode
- `false` - see Hashbang mode
- default: `false`
-
-- **hashPrefix(prefix)**: {string}
- prefix used for Hashbang URLs (used in Hashbang mode or in legacy browser in Html5 mode)
- default: `""`
-
-### Example configuration
-```js
-$locationProvider.html5Mode(true).hashPrefix('!');
-```
-
-## Getter and setter methods
-
-`$location` service provides getter methods for read-only parts of the URL (absUrl, protocol, host,
-port) and getter / setter methods for url, path, search, hash:
-```js
-// get the current path
-$location.path();
-
-// change the path
-$location.path('/newValue')
-```
-
-All of the setter methods return the same `$location` object to allow chaining. For example, to
-change multiple segments in one go, chain setters like this:
-
-```js
-$location.path('/newValue').search({key: value});
-```
-
-## Replace method
-
-There is a special `replace` method which can be used to tell the $location service that the next
-time the $location service is synced with the browser, the last history record should be replaced
-instead of creating a new one. This is useful when you want to implement redirection, which would
-otherwise break the back button (navigating back would retrigger the redirection). To change the
-current URL without creating a new browser history record you can call:
-
-```js
- $location.path('/someNewPath');
- $location.replace();
- // or you can chain these as: $location.path('/someNewPath').replace();
-```
-
-Note that the setters don't update `window.location` immediately. Instead, the `$location` service is
-aware of the {@link ng.$rootScope.Scope scope} life-cycle and coalesces multiple `$location`
-mutations into one "commit" to the `window.location` object during the scope `$digest` phase. Since
-multiple changes to the $location's state will be pushed to the browser as a single change, it's
-enough to call the `replace()` method just once to make the entire "commit" a replace operation
-rather than an addition to the browser history. Once the browser is updated, the $location service
-resets the flag set by `replace()` method and future mutations will create new history records,
-unless `replace()` is called again.
-
-### Setters and character encoding
-You can pass special characters to `$location` service and it will encode them according to rules
-specified in [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt). When you access the methods:
-
-- All values that are passed to `$location` setter methods, `path()`, `search()`, `hash()`, are
-encoded.
-- Getters (calls to methods without parameters) return decoded values for the following methods
-`path()`, `search()`, `hash()`.
-- When you call the `absUrl()` method, the returned value is a full url with its segments encoded.
-- When you call the `url()` method, the returned value is path, search and hash, in the form
-`/path?search=a&b=c#hash`. The segments are encoded as well.
-
-
-# Hashbang and HTML5 Modes
-
-`$location` service has two configuration modes which control the format of the URL in the browser
-address bar: **Hashbang mode** (the default) and the **HTML5 mode** which is based on using the
-HTML5 [History API](http://www.w3.org/TR/html5/history.html). Applications use the same API in
-both modes and the `$location` service will work with appropriate URL segments and browser APIs to
-facilitate the browser URL change and history management.
-
-
-
-
-
-
-
-
-
Hashbang mode
-
HTML5 mode
-
-
-
-
-
-
-
configuration
-
the default
-
{ html5Mode: true }
-
-
-
-
URL format
-
hashbang URLs in all browsers
-
regular URLs in modern browser, hashbang URLs in old browser
-
-
-
-
<a href=""> link rewriting
-
no
-
yes
-
-
-
-
requires server-side configuration
-
no
-
yes
-
-
-
-
-## Hashbang mode (default mode)
-
-In this mode, `$location` uses Hashbang URLs in all browsers.
-
-### Example
-
-```js
-it('should show example', inject(
- function($locationProvider) {
- $locationProvider.html5Mode(false);
- $locationProvider.hashPrefix('!');
- },
- function($location) {
- // open http://example.com/base/index.html#!/a
- $location.absUrl() == 'http://example.com/base/index.html#!/a'
- $location.path() == '/a'
-
- $location.path('/foo')
- $location.absUrl() == 'http://example.com/base/index.html#!/foo'
-
- $location.search() == {}
- $location.search({a: 'b', c: true});
- $location.absUrl() == 'http://example.com/base/index.html#!/foo?a=b&c'
-
- $location.path('/new').search('x=y');
- $location.absUrl() == 'http://example.com/base/index.html#!/new?x=y'
- }
-));
-```
-
-### Crawling your app
-
-To allow indexing of your AJAX application, you have to add special meta tag in the head section of
-your document:
-
-```html
-
-```
-
-This will cause crawler bot to request links with `_escaped_fragment_` param so that your server
-can recognize the crawler and serve a HTML snapshots. For more information about this technique,
-see [Making AJAX Applications
-Crawlable](http://code.google.com/web/ajaxcrawling/docs/specification.html).
-
-## HTML5 mode
-
-In HTML5 mode, the `$location` service getters and setters interact with the browser URL address
-through the HTML5 history API, which allows for use of regular URL path and search segments,
-instead of their hashbang equivalents. If the HTML5 History API is not supported by a browser, the
-`$location` service will fall back to using the hashbang URLs automatically. This frees you from
-having to worry about whether the browser displaying your app supports the history API or not; the
-`$location` service transparently uses the best available option.
-
-- Opening a regular URL in a legacy browser -> redirects to a hashbang URL
-- Opening hashbang URL in a modern browser -> rewrites to a regular URL
-
-### Example
-
-```js
-it('should show example', inject(
- function($locationProvider) {
- $locationProvider.html5Mode(true);
- $locationProvider.hashPrefix('!');
- },
- function($location) {
- // in browser with HTML5 history support:
- // open http://example.com/#!/a -> rewrite to http://example.com/a
- // (replacing the http://example.com/#!/a history record)
- $location.path() == '/a'
-
- $location.path('/foo');
- $location.absUrl() == 'http://example.com/foo'
-
- $location.search() == {}
- $location.search({a: 'b', c: true});
- $location.absUrl() == 'http://example.com/foo?a=b&c'
-
- $location.path('/new').search('x=y');
- $location.url() == 'new?x=y'
- $location.absUrl() == 'http://example.com/new?x=y'
-
- // in browser without html5 history support:
- // open http://example.com/new?x=y -> redirect to http://example.com/#!/new?x=y
- // (again replacing the http://example.com/new?x=y history item)
- $location.path() == '/new'
- $location.search() == {x: 'y'}
-
- $location.path('/foo/bar');
- $location.path() == '/foo/bar'
- $location.url() == '/foo/bar?x=y'
- $location.absUrl() == 'http://example.com/#!/foo/bar?x=y'
- }
-));
-```
-
-### Fallback for legacy browsers
-
-For browsers that support the HTML5 history API, `$location` uses the HTML5 history API to write
-path and search. If the history API is not supported by a browser, `$location` supplies a Hasbang
-URL. This frees you from having to worry about whether the browser viewing your app supports the
-history API or not; the `$location` service makes this transparent to you.
-
-### Html link rewriting
-
-When you use HTML5 history API mode, you will need different links in different browsers, but all you
-have to do is specify regular URL links, such as: `link`
-
-When a user clicks on this link,
-
-- In a legacy browser, the URL changes to `/index.html#!/some?foo=bar`
-- In a modern browser, the URL changes to `/some?foo=bar`
-
-
-In cases like the following, links are not rewritten; instead, the browser will perform a full page
-reload to the original link.
-
-- Links that contain `target` element
- Example: `link`
-- Absolute links that go to a different domain
- Example: `link`
-- Links starting with '/' that lead to a different base path when base is defined
- Example: `link`
-
-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.
-
-To prevent this, you can set your base href for the app to `` and then prefix links
-to URLs that should be handled with `.`. Now, links to locations, which are not to be routed by Angular,
-are not prefixed with `.` and will not be intercepted by the `otherwise` rule in your `$routeProvider`.
-
-
-### Server side
-
-Using this mode requires URL rewriting on server side, basically you have to rewrite all your links
-to entry point of your application (e.g. index.html)
-
-### Crawling your app
-
-If you want your AJAX application to be indexed by web crawlers, you will need to add the following
-meta tag to the HEAD section of your document:
-
-```html
-
-```
-
-This statement causes a crawler to request links with an empty `_escaped_fragment_` parameter so that
-your server can recognize the crawler and serve it HTML snapshots. For more information about this
-technique, see [Making AJAX
-Applications Crawlable](http://code.google.com/web/ajaxcrawling/docs/specification.html).
-
-### Relative links
-
-Be sure to check all relative links, images, scripts etc. You must either specify the url base in
-the head of your main html file (``) or you must use absolute urls
-(starting with `/`) everywhere because relative urls will be resolved to absolute urls using the
-initial absolute url of the document, which is often different from the root of the application.
-
-Running Angular apps with the History API enabled from document root is strongly encouraged as it
-takes care of all relative link issues.
-
-### Sending links among different browsers
-
-Because of rewriting capability in HTML5 mode, your users will be able to open regular url links in
-legacy browsers and hashbang links in modern browser:
-
-- Modern browser will rewrite hashbang URLs to regular URLs.
-- Older browsers will redirect regular URLs to hashbang URLs.
-
-### Example
-
-Here you can see two `$location` instances, both in **Html5 mode**, but on different browsers, so
-that you can see the differences. These `$location` services are connected to a fake browsers. Each
-input represents address bar of the browser.
-
-Note that when you type hashbang url into first browser (or vice versa) it doesn't rewrite /
-redirect to regular / hashbang url, as this conversion happens only during parsing the initial URL
-= on page reload.
-
-In this examples we use ``
-
-
-
-
-
-
- function FakeBrowser(initUrl, baseHref) {
- this.onUrlChange = function(fn) {
- this.urlChange = fn;
- };
-
- this.url = function() {
- return initUrl;
- };
-
- this.defer = function(fn, delay) {
- setTimeout(function() { fn(); }, delay || 0);
- };
-
- this.baseHref = function() {
- return baseHref;
- };
-
- this.notifyWhenOutstandingRequests = angular.noop;
- }
-
- var browsers = {
- html5: new FakeBrowser('http://www.example.com/base/path?a=b#h', '/base/index.html'),
- hashbang: new FakeBrowser('http://www.example.com/base/index.html#!/path?a=b#h', '/base/index.html')
- };
-
- function Html5Cntl($scope, $location) {
- $scope.$location = $location;
- }
-
- function HashbangCntl($scope, $location) {
- $scope.$location = $location;
- }
-
- function initEnv(name) {
- var root = angular.element(document.getElementById(name + '-mode'));
- // We must kill a link to the injector for this element otherwise angular will
- // complain that it has been bootstrapped already.
- root.data('$injector', null);
- angular.bootstrap(root, [function($compileProvider, $locationProvider, $provide){
- $locationProvider.html5Mode(true).hashPrefix('!');
-
- $provide.value('$browser', browsers[name]);
- $provide.value('$sniffer', {history: name == 'html5'});
-
- $compileProvider.directive('ngAddressBar', function() {
- return function(scope, elm, attrs) {
- var browser = browsers[attrs.browser],
- input = angular.element('').val(browser.url()),
- delay;
-
- input.on('keypress keyup keydown', function() {
- if (!delay) {
- delay = setTimeout(fireUrlChange, 250);
- }
- });
-
- browser.url = function(url) {
- return input.val(url);
- };
-
- elm.append('Address: ').append(input);
-
- function fireUrlChange() {
- delay = null;
- browser.urlChange(input.val());
- }
- };
- });
- }]);
- root.on('click', function(e) {
- e.stopPropagation();
- });
- }
-
- initEnv('html5');
- initEnv('hashbang');
-
-
-
-
-# Caveats
-
-## Page reload navigation
-
-The `$location` service allows you to change only the URL; it does not allow you to reload the
-page. When you need to change the URL and reload the page or navigate to a different page, please
-use a lower level API, {@link ng.$window $window.location.href}.
-
-## Using $location outside of the scope life-cycle
-
-`$location` knows about Angular's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
-the browser it updates the `$location` and calls `$apply` so that all $watchers / $observers are
-notified.
-When you change the `$location` inside the `$digest` phase everything is ok; `$location` will
-propagate this change into browser and will notify all the $watchers / $observers.
-When you want to change the `$location` from outside Angular (for example, through a DOM Event or
-during testing) - you must call `$apply` to propagate the changes.
-
-## $location.path() and ! or / prefixes
-
-A path should always begin with forward slash (`/`); the `$location.path()` setter will add the
-forward slash if it is missing.
-
-Note that the `!` prefix in the hashbang mode is not part of `$location.path()`; it is actually
-hashPrefix.
-
-
-# Testing with the $location service
-
-When using `$location` service during testing, you are outside of the angular's {@link
-ng.$rootScope.Scope scope} life-cycle. This means it's your responsibility to call `scope.$apply()`.
-
-```js
-describe('serviceUnderTest', function() {
- beforeEach(module(function($provide) {
- $provide.factory('serviceUnderTest', function($location){
- // whatever it does...
- });
- });
-
- it('should...', inject(function($location, $rootScope, serviceUnderTest) {
- $location.path('/new/path');
- $rootScope.$apply();
-
- // test whatever the service should do...
-
- }));
-});
-```
-
-
-# Migrating from earlier AngularJS releases
-
-In earlier releases of Angular, `$location` used `hashPath` or `hashSearch` to process path and
-search methods. With this release, the `$location` service processes path and search methods and
-then uses the information it obtains to compose hashbang URLs (such as
-`http://server.com/#!/path?search=a`), when necessary.
-
-## Changes to your code
-
-
-
-
-
Navigation inside the app
-
Change to
-
-
-
-
-
-
$location.href = value $location.hash = value $location.update(value) $location.updateHash(value)
-
$location.path(path).search(search)
-
-
-
-
$location.hashPath = path
-
$location.path(path)
-
-
-
-
$location.hashSearch = search
-
$location.search(search)
-
-
-
-
Navigation outside the app
-
Use lower level API
-
-
-
-
$location.href = value $location.update(value)
-
$window.location.href = value
-
-
-
-
$location[protocol | host | port | path | search]
-
$window.location[protocol | host | port | path | search]
-
-## Two-way binding to $location
-
-The Angular's compiler currently does not support two-way binding for methods (see [issue](https://github.com/angular/angular.js/issues/404)). If you should require two-way binding
-to the $location object (using {@link input[text] ngModel} directive on an input
-field), you will need to specify an extra model property (e.g. `locationPath`) with two watchers
-which push $location updates in both directions. For example:
-
-
-
-
-
-
-
-function LocationController($scope, $location) {
- $scope.$watch('locationPath', function(path) {
- $location.path(path);
- });
- $scope.$watch(function() {
- return $location.path();
- }, function(path) {
- $scope.locationPath = path;
- });
-}
-
-
-
-# Related API
-
-* {@link ng.$location $location API}
-
-
-
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'];
-```
-
-
-
-
-
Let's try this simple notify service, injected into the controller...
-
-
-
(you have to click 3 times to see an alert)
-
-
-
-
- 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'];
-
-
-
- it('should test service', function() {
- expect(element(by.id('simple')).element(by.model('message')).getAttribute('value'))
- .toEqual('test');
- });
-
-
-
-## 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:
-
-
-
-
-
Let's try the notify service, that is implicitly injected into the controller...
-
-
-
(you have to click 3 times to see an alert)
-
-
-
-
- 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);
- };
- }
-
-
-
-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}.
+
+
+**Note:** Like other core Angular identifiers built-in services always start with `$`
+(i.e. `$http`).
+
+
+
+## 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.
+
+
+
+
+
Let's try this simple notify service, injected into the controller...
+
+### 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);
+ ```
+
+
+**Best Practice:** Use the array annotation shown above.
+
+
+### 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:
+
+
+
+
+
Let's try the notify service, that is implicitly injected into the controller...
+**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.
+
+
+
+## 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}
--
cgit v1.2.3