Original address: Http://code.angularjs.org/1.0.2/docs/guide/dev_guide.services. $location
I. What does it does?
$location service parses the URL in the address bar of the browser (based on window.location), so that we can easily use the URL inside the app. Changing the URL in the Address bar responds to the $location service, and the URL is modified in $location and also responds to the address bar.
$location Services:
- Exposes the URL of the current browser address bar, so we can
- Note and observe URLs
- Change URL
- Synchronize URLs with the browser when the user does the following:
- Change the Address bar
- Click the Back or Forward button (or click a history link).
- Click a link
- Depicts a URL object as a series of methods (Protocol,host,path,search,hash).
1. Compare $location and Window.location
1) Purpose: window.location and $location services allow read and write access to the location of the current browser.
2) API:window.location exposes an unprocessed object with some properties that can be modified directly, while the $location service exposes some jquery-style getter/setter methods.
3) Integration with angular application declaration cycle: $location know the stages of all internal declaration cycles, integrate with $watch, and window.location.
4) seamless integration with HTML5 API: Yes (with a fallback for legacy browsers, is there a compatible means for a lower version of the browser? ), while Window.location is not.
5) know the document root (Docroot) or context in which the app is loaded: Window.location No, Wnidow.location.path will return/docroot/subpath; $location.path ( ) returns the true Docroot.
2. When is should I use $location?
In the app, any need to respond to changes to the current URL, or to change the URL of the current browser.
3. What does it does?
When the URL of the browser changes, it does not cause the page to reload (reload). If you need to do this (change the address to implement page reload), use the lower-level API, $window. Location.href.
Ii. general overview of the API (overview of the API)
$location service can behave differently depending on the configuration it initializes. The default configuration is suitable for most applications, other configurations are customizable, and some new features can be opened.
When the $location service is initialized, we can use it in the jquery style getter, setter method, allowing us to get or change the URL of the current browser.
1. $location Service Configuration
To configure the $location service, you need to obtain $locationprovider (Http://code.angularjs.org/1.0.2/docs/api/ng. $locationProvider) and set the following parameters:
- Html5mode (Mode): {boolean},true-see HTML5 mode;false-see Hashbang mode, default: false. (The following chapters will explain the various mode)
- Hashprefix (prefix): {String},hashbang uses a prefix (Html5mode is false, use Hashbang mode to accommodate browsers that do not support HTML5 mode), default: '! '
2. Getter and Setter methods
The $location service provides getter methods for the read-only URL portion (Absurl,protocol,host,port), and also provides Url,path,search,hash getter and setter methods.
Get the current path $location. path ();
Change the path $location. Path ('/newvalue ')
All setter methods return the same $location object to implement the chained syntax. For example, to modify multiple attributes in one sentence, the chained setter method is similar:
$location. Path ('/newvalue '). Search ({key:value});
There is a special replace method that can be used to tell the $location service to use a path instead of the latest history when synchronizing with the browser the next time, instead of creating a new history. The Replace method is useful when we want to implement redirection (redirection) and do not want to invalidate the Back button (back button to re-trigger redirection). If you want to change the current URL without creating a new history, we can do this:
$location. Path ('/somenewpath '). replace ();
Note that the setter method does not update window.location immediately. Instead, the $location service knows the scope life cycle and merges multiple $location into one, and commits to the Window.location object in the $digest phase of the scope. Because $location changes in multiple states are merged into a single change, in the browser, only the replace () method is called once, so that the entire commit has only one replace (), which does not cause the browser to create additional history. Once the browser is updated, the $location service resets the flag bit through the Replace () method, and future changes will create a new history, unless replace () is called again.
Setter and character encoding
We can pass in special characters to the $location service, and the service will encode them automatically according to the RFC3986 standard. When we access these methods:
- The values of all the setter methods passed into the $location, path (), search (), hash (), are encoded.
- The values returned by the Getter method (no arguments) are decoded, such as Path (), search (), hash ().
- When we call the Absurl () method, the value returned is the full URL that contains the encoded part.
- When we call the URL () method, we return the encoded URLs that contain the path, search, and hash portions, such as/path?search=1&b=c#hash.
Iii. Hashbang and HTML5 Modes
The $location service has two configuration modes to control the URL format of the browser address bar: Hashbang mode (default) and HTML5 mode based on the HTML5 history API. In both modes, the app uses the same API, $location service works with the right URL fragment, browser API, and helps us with browser URL changes and historical management.
1. Hashbang mode (default mode)
In this mode, $location use the Hashbang URL in all browsers. See the code snippet below to learn more:
It (' Should show example ', Inject ( function ($locationProvider) { $locationProvider. Html5mode = false; $locationProvider. Hashprefix = '! '; }, function ($location) { //Open http://host.com/base/index.html#!/ A $location. Absurl () = = ' http://host.com/base/index.html#!/a '; $location. Path () = = ' a '; $location. Path ('/foo '); $location. Absurl () = = ' Http://host.com/base/index.html#!/foo '; $location. Search () = = {};//search, returns an empty object $location. Search ({A: ' B ', c:true}); $location. Absurl () = = ' Http://host.com/base/index.html#!/foo?a=b&c '; $location. Path ('/new '). Search (' x=y ');//You can change search by string, and each time you set up search, the previous search $location will be overwritten . Absurl () = = ' Http://host.com/base/index.html#!/new?x=y '; }));
Crawling your app (allows Google to index our apps)
If we want our AJAX applications to be indexed, we need to add a special meta tag to the head:
<meta name= "Fragment" content= "!"/>
Doing so will allow the bot to use the _escaped_fragment_ parameter to request the current link, let our server know the bot, and provide the corresponding HTML snapshot. To learn more about this technology, you can view Https://developers.google.com/webmasters/ajax-crawling/docs/specification?hl=zh-CN
Four, HTML5 mode
In HTML5 mode, the getter, setter of the $location service interacts with the browser URL through the HTML5 's history API, allowing the use of the regular path, search module instead of the Hashbang mode. If some browsers do not support the HTML5 history API, $location service is automatically returned to the mode using the Hashbang URL. The use of the $location service is the right and best choice for us to be free from the fear that it is not clear whether the browser that shows our app supports the history API.
- Opening a regular URL in a legacy browser will convert to Hashbangurl.
- Opening a hashbangurl in a modern browser will be rewritten as a regular URL.
1. Forward compatibility with legacy browsers
For browsers that support the HTML5 history API, $location back to using them to write path and search. If the browser does not support the history API, $location will switch to providing the Hashbang URL. This is an automatic conversion of the $location service.
2. HTML Link Rewriting
When we use the history API mode, we need different links for different browsers, but we only need to provide a regular URL, such as <a href= "/some?foo=bar" >link</a>
When the user clicks the hyperlink:
- In the old browser, the URL will be changed to/index.html#!/some?foo=bar
- In a modern browser, the URL is changed to/some?foo=bar
In the following scenario, the link is not rewritten, but the page is loaded into the corresponding URL:
- Hyperlink with target: <a href= "/ext/link?a=b" target= "_self" >link</a>
- Absolute links to different domain: <a href= "http://angularjs.org/" >link</a>
- After the base path is set, hyperlinks to different base paths begin with "/": <a href= "/not-my-base/link" >link</a>
3. Server Side
Using this method, request URL redirection on the server, usually we need to redirect all of our links to our app. (e.g. index.html).
4. Crawling your App
Same as before
5. Relative Links
Make sure to check all relative links, pictures, scripts, and so on. We must specify the base URL (<base href= "/my-base" >) in
We strongly encourage you to run the angular app in document root that allows you to use the history API, as this is a good way to take care of relative link issues.
6. Sending links among different browsers
(this explains the two modes of the address can be adapted to different browsers, automatic conversion, and repeat once again ...) )
7. Example
In this example, you can see two $location instances, two are HTML5 mode, but on different browsers, so we can see the difference between the two. These $location services are connected to two fake "browsers". Each input represents the address bar of a browser.
Note that when we enter the Hashbang address to the first "browser" (or the second one?). ), it does not rewrite or redirect additional URLs, and this conversion process will only occur at page reload.
<! DOCTYPE html> V. Additional instructions
1. Page Reload Navigation
The $location service only allows us to change the URL; it does not allow us to reload the page (reload). When we need to change the URL and reload page or jump to another page, we need to use the low-level point API, $window. Location.href.
2. Using $location outside of the scope life-cycle
$location know angular's scope life-cycle. When the URL of the browser changes, it updates the $location, and calls $apply, so all $watcher and $observer will be notified. When we modify the $location in the $digest phase, there will be no problem; $location will propagate this modification to the browser and notify all $watcher, $observer. When we need to change $location outside of angular (for example, in DOM events or in tests), we must call $apply to propagate this change.
3. $location. Path () and! Or/prefixes
Path can start directly with "/", $location. Path () setter will be automatically mended when value does not start with "/".
Attention "!" prefix, in Hashbang mode, is not part of the $location.path (). It's just hashprefix.
VI. Testing with the $location service
When using the $location service in the test, it is outside the angular scope life-cycle. This means that we need to be responsible for calling scope.apply ().
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 ...});
Vii. migrating from earlier AngularJS releases
In earlier angular, $location used Hashpath or hashsearch to process the path and search methods. In this release, when needed, $location service processes the path and search methods, and then uses the obtained information to form the Hashbang URL (for example, Http://server.com/#!/path?search=a).
Viii. two-way binding to $location
Angular compiler currently does not support bidirectional binding of methods (https://github.com/angular/angular.js/issues/404). If we want to implement two-way binding on the $location object (using ngmodel directive in input), we need to specify an additional model property (for example: Locationpath) and add two $watch to listen for $ in two directions Location updates, such as:
<input type= "text" ng-model= "Locationpath"/>
Js-controller$scope. $watch (' Locationpath ', function (path) { $location. Path (path);); $scope. $watch (' $ Location.path () ', function (path) { scope.locationpath = path;});
Angularjs Study notes--using $location