• 沒有找到結果。

Changing Views with Routes and $location

在文檔中 Brad Green and Shyam Seshadri (頁 50-53)

return words.join(' ');

};

return titleCaseFilter;

});

With a template like this:

<body ng-app='HomeModule' ng-controller="HomeController">

<h1>{{pageHeading | titleCase}}</h1>

</body>

and inserting the pageHeading as a model variable via a controller:

function HomeController($scope) {

$scope.pageHeading = 'behold the majesty of your page title';

}

we would see something resembling Figure 2-3.

Figure 2-3. Title case filter

Changing Views with Routes and $location

Though AJAX apps are technically single-page apps (in the sense that they only load an HTML page on the first request, and then just update areas within the DOM thereafter), we usually have multiple sub-page views that we show or hide from the user, as appro‐

priate.

We can use Angular’s $route service to manage this scenario for us. Routes let you specify that, for a given URL that the browser points to, Angular should load and display a template, and instantiate a controller to provide context for the template.

You create routes in your application by calling functions on the $routeProvider service as a configuration block. It goes something like this pseudo-code:

var someModule = angular.module('someModule', [...module dependencies...]) someModule.config(function($routeProvider) {

$routeProvider.

when('url', {controller:aController, templateUrl:'/path/to/tempate'}).

when(...other mappings for your app...).

otherwise(...what to do if nothing else matches...);

)};

The preceding code says that when the browser’s URL changes to the specified URL, Angular will load the template in /path/to/template, and associate the root element of this template with aController (as if we’d typed ng-controller=aController).

The otherwise() call in the last line tells the route where to go if nothing else matches.

Let’s put it to use. We’re building an email app that will easily win out over Gmail, Hotmail, and all the others. We’ll call it…A-Mail. For now, let’s start simply. We’ll have a first view that displays a list of email messages with a date, title, and the sender. When you click a message, it should show you a new view with the body of that message.

Due to browser security restrictions, if you’re trying the code out your‐

self, you’ll need to serve it from a web server instead of just file://. If you have python installed, you could serve it by executing python -m Sim pleHTTPServer 8888 from your working directory.

For the main template, we’ll do something a bit different. Instead of putting everything in the first page loaded, we’ll just create a layout template that we’ll put our views into.

We’ll place everything that persists from view to view, like our menus, here. In this case, we’ll just display a heading with the name of our app. We’ll then use the ng-view directive to tell Angular where we want our views to appear.

index.html

<html ng-app="AMail">

<head>

<script src="src/angular.js"></script>

<script src="src/controllers.js"></script>

</head>

<body>

<h1>A-Mail</h1>

<div ng-view></div>

</body>

</html>

As our view templates will be inserted into the shell we just created, we can write them as partial HTML documents. For the email list, we’ll use ng-repeat to iterate through a list of messages and render them into a table.

list.html

<table>

<tr>

<td><strong>Sender</strong></td>

<td><strong>Subject</strong></td>

<td><strong>Date</strong></td>

Changing Views with Routes and $location | 39

</tr>

<tr ng-repeat='message in messages'>

<td>{{message.sender}}</td>

<td><a href='#/view/{{message.id}}'>{{message.subject}}</td>

<td>{{message.date}}</td>

</tr>

</table>

Notice here that we’re going to let the user navigate to a particular message by clicking on the subject. We’ve data bound the URL to message.id, so clicking on a message with id=1 will take the user to /#/view/1. We’ll use this navigation-by-url, also known as deep-linking, in the message detail view’s controller, to make a particular message available to the detail view.

To create this message detail view, we’ll create a template that displays properties from a single message object.

detail.html

<div><strong>Subject:</strong> {{message.subject}}</div>

<div><strong>Sender:</strong> {{message.sender}}</div>

<div><strong>Date:</strong> {{message.date}}</div>

<div>

<strong>To:</strong>

<span ng-repeat='recipient in message.recipients'>{{recipient}} </span>

<div>{{message.message}}</div>

<a href='#/'>Back to message list</a>

Now, to associate these templates with some controllers, we’ll configure the $routePro vider with the URLs that invoke our controllers and templates.

controllers.js

// Create a module for our core AMail services var aMailServices = angular.module('AMail', []);

// Set up our mappings between URLs, templates, and controllers function emailRouteConfig($routeProvider) {

$routeProvider.

when('/', {

controller: ListController, templateUrl: 'list.html' }).

// Notice that for the detail view, we specify a parameterized URL component // by placing a colon in front of the id

when('/view/:id', {

controller: DetailController, templateUrl: 'detail.html' }).

otherwise({

redirectTo: '/'

});

}

// Set up our route so the AMail service can find it aMailServices.config(emailRouteConfig);

// Some fake emails messages = [{

id: 0, sender: '[email protected]', subject: 'Hi there, old friend', date: 'Dec 7, 2013 12:32:00', recipients: ['[email protected]'], message: 'Hey, we should get together for lunch sometime and catch up.' +'There are many things we should collaborate on this year.'

}, {

id: 1, sender: '[email protected]', subject: 'Where did you leave my laptop?',

date: 'Dec 7, 2013 8:15:12', recipients: ['[email protected]'], message: 'I thought you were going to put it in my desk drawer.' +'But it does not seem to be there.'

}, {

id: 2, sender: '[email protected]', subject: 'Lost python', date: 'Dec 6, 2013 20:35:02', recipients: ['[email protected]'], message: "Nobody panic, but my pet python is missing from her cage.' +'She doesn't move too fast, so just call me if you see her."

}, ];

// Publish our messages for the list template function ListController($scope) {

$scope.messages = messages;

}

// Get the message id from the route (parsed from the URL) and use it to // find the right message object.

function DetailController($scope, $routeParams) { $scope.message = messages[$routeParams.id];

}

We’ve created the basic structure for an app with many views. We switch views by changing the URL. This means that the forward and back buttons just work for users.

Users are able to bookmark and email links to views within the app, even though there is only one real HTML page.

在文檔中 Brad Green and Shyam Seshadri (頁 50-53)