Files
angular.js/docs/cookbook.deeplinking.ngdoc
Vojta Jina 1abdc097b2 JSTD adapter for running e2e tests
Couple of changes into angular.scenario runner:
 - add autotest config (runs tests when document ready)
 - update ObjectModel (forwards events)
 - use only one ObjectModel instance for all outputters
 - expose error msg and line number in ObjectModel.Spec and ObjectModel.Step
 - fix generating spec.ids
 - fix 'html' output so that it does not mutate ObjectModel

Couple of changes into docs / generator:
 - rename copy -> copyTpl
 - move docs/static into docs/examples (to avoid conflict with jstd proxy)

Running all docs e2e tests:
========================================================
1/ compile angular-scenario, jstd-scenario-adapter
>> rake compile

2/ build docs
>> rake docs

3/ start jstd server
>> ./server-scenario.sh

4/ capture some browser

5/ run node server to serve static content
>> node ../lib/nodeserver/server.js

6/ run tests
>> ./test-scenario.sh
2011-05-19 09:43:56 -07:00

115 lines
4.1 KiB
Plaintext

@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 `#` 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:
* {@link ./examples/settings.html}
* {@link ./examples/welcome.html}
<doc:example>
<doc:source>
<script>
AppCntl.$inject = ['$route']
function AppCntl($route) {
// define routes
$route.when("", {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);
}
};
function SettingsCntl(){
this.cancel();
}
SettingsCntl.prototype = {
cancel: function(){
this.form = angular.copy(this.person);
},
save: function(){
angular.copy(this.form, this.person);
window.location.hash = "#";
}
};
</script>
<div ng:controller="AppCntl">
<h1>Your App Chrome</h1>
[ <a href="#">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 angular.service.$route $route} service with the proper URL routes.
* The {@link angular.service.$route $route} service then watches the URL and instantiates the
appropriate controller when the URL changes.
* The {@link 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.