mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-20 16:30:26 +00:00
- Configure our docs app to use new $location with html5 history api! - Update simple node web server to serve index.html for all links (rewritting). - Update .htaccess file to serve index.html for all links (rewritting). - At runtime determine the base href path and attach it to the DOM. We needed the absolute URL to get all browsers to work well. - Because of the above, we also need to dynamically determine all needed js/css resources and add them to the DOM. This was needed because FF6 would eagerly fetch resources with wrong URL since the base element is added to the dom at runtime. - All content html files were moved to the partials directory, because with the new html5 urls it was impossible to tell if request for http://domain/api/angular.filter.html was an html5 url for the html filter doc page, or an xhr/appcache request for the content html file for the html filter. f
117 lines
4.3 KiB
Text
117 lines
4.3 KiB
Text
@workInProgress
|
|
@ngdoc overview
|
|
@name Cookbook: Deep Linking
|
|
@description
|
|
|
|
Deep linking allows you to encode the state of the application in the URL so that it can be
|
|
bookmarked and the application can be restored from the URL to the same state.
|
|
|
|
While <angular/> does not force you to deal with bookmarks in any particular way, it has services
|
|
which make the common case described here very easy to implement.
|
|
|
|
# Assumptions
|
|
|
|
Your application consists of a single HTML page which bootstraps the application. We will refer
|
|
to this page as the chrome.
|
|
Your application is divided into several screens (or views) which the user can visit. For example,
|
|
the home screen, settings screen, details screen, etc. For each of these screens, we would like to
|
|
assign a URL so that it can be bookmarked and later restored. Each of these screens will be
|
|
associated with a controller which define the screen's behavior. The most common case is that the
|
|
screen will be constructed from an HTML snippet, which we will refer to as the partial. Screens can
|
|
have multiple partials, but a single partial is the most common construct. This example makes the
|
|
partial boundary visible using a blue line.
|
|
|
|
You can make a routing table which shows which URL maps to which partial view template and which
|
|
controller.
|
|
|
|
# Example
|
|
|
|
In this example we have a simple app which consist of two screens:
|
|
|
|
* Welcome: url `welcome` Show the user contact information.
|
|
* Settings: url `settings` Show an edit screen for user contact information.
|
|
|
|
|
|
The two partials are defined in the following URLs:
|
|
|
|
* <a href="./examples/settings.html" ng:ext-link>./examples/settings.html</a>
|
|
* <a href="./examples/welcome.html" ng:ext-link>./examples/welcome.html</a>
|
|
|
|
<doc:example>
|
|
<doc:source>
|
|
<script>
|
|
AppCntl.$inject = ['$route']
|
|
function AppCntl($route) {
|
|
// define routes
|
|
$route.when("/welcome", {template:'./examples/welcome.html', controller:WelcomeCntl});
|
|
$route.when("/settings", {template:'./examples/settings.html', controller:SettingsCntl});
|
|
$route.parent(this);
|
|
|
|
// initialize the model to something useful
|
|
this.person = {
|
|
name:'anonymous',
|
|
contacts:[{type:'email', url:'anonymous@example.com'}]
|
|
};
|
|
}
|
|
|
|
function WelcomeCntl($route){}
|
|
WelcomeCntl.prototype = {
|
|
greet: function(){
|
|
alert("Hello " + this.person.name);
|
|
}
|
|
};
|
|
|
|
SettingsCntl.$inject = ['$location'];
|
|
function SettingsCntl($location){
|
|
this.$location = $location;
|
|
this.cancel();
|
|
}
|
|
SettingsCntl.prototype = {
|
|
cancel: function(){
|
|
this.form = angular.copy(this.person);
|
|
},
|
|
|
|
save: function(){
|
|
angular.copy(this.form, this.person);
|
|
this.$location.path('/welcome');
|
|
}
|
|
};
|
|
</script>
|
|
<div ng:controller="AppCntl">
|
|
<h1>Your App Chrome</h1>
|
|
[ <a href="welcome">Welcome</a> | <a href="settings">Settings</a> ]
|
|
<hr/>
|
|
<span style="background-color: blue; color: white; padding: 3px;">
|
|
Partial: {{$route.current.template}}
|
|
</span>
|
|
<ng:view style="border: 1px solid blue; margin: 0; display:block; padding:1em;"></ng:view>
|
|
<small>Your app footer </small>
|
|
</div>
|
|
</doc:source>
|
|
<doc:scenario>
|
|
it('should navigate to URL', function(){
|
|
element('a:contains(Welcome)').click();
|
|
expect(element('ng\\:view').text()).toMatch(/Hello anonymous/);
|
|
element('a:contains(Settings)').click();
|
|
input('form.name').enter('yourname');
|
|
element(':button:contains(Save)').click();
|
|
element('a:contains(Welcome)').click();
|
|
expect(element('ng\\:view').text()).toMatch(/Hello yourname/);
|
|
});
|
|
</doc:scenario>
|
|
</doc:example>
|
|
|
|
|
|
|
|
# Things to notice
|
|
|
|
* Routes are defined in the `AppCntl` class. The initialization of the controller causes the
|
|
initialization of the {@link api/angular.service.$route $route} service with the proper URL
|
|
routes.
|
|
* The {@link api/angular.service.$route $route} service then watches the URL and instantiates the
|
|
appropriate controller when the URL changes.
|
|
* The {@link api/angular.widget.ng:view ng:view} widget loads the view when the URL changes. It
|
|
also
|
|
sets the view scope to the newly instantiated controller.
|
|
* Changing the URL is sufficient to change the controller and view. It makes no difference whether
|
|
the URL is changed programatically or by the user.
|