AngularJS中使用路由和$location切换视图
虽然从技术上来说Ajax应用确实是单页面应用(即在第一个请求时加载一个HTML页面,后面只刷新DOM中的局部区域),但是很多时候,出于各种原因,我们需要为用户展示或者隐藏一些子页面的视图。
我们可以利用Angular的$route服务来管理这种场景。可以使用路由服务这样定义:对于浏览器所指向的特定URL,Angular将会加载并显示一个模板,并实例化一个控制器来为模板提供内容。
在应用中,可以通过调用$routeProvider服务上的函数来创建路由,把需要创建的路由当成一个配置块传给这些函数即可。
下面我们将这一技术投入应用,构建一款email应用,会有一个首页视图,里面将会展示邮件列表,其中带有日期、标题和发件人。当点击一份邮件时,将会打开一个新视图来展示邮件内容。
在主模板中,我们不会把所有东西都放在第一个加载的页面中,而是仅仅创建一个布局模板,然后再用这个模板来容纳各种视图。在主视图中,我们将会把多个视图共有的东西都放在里面,例如菜单。在这个例子中,我们仅仅把应用的标题放在里面,然后再用ng-view指令来告诉Angular把视图显示在哪。
index.html
<html ng-app="AMail"> <head> <script src="lib/angular/angular.js"></script> <script src="controller/controllers.js"></script> </head> <body> <h1>A-Mail</h1> <div ng-view></div> </body> </html>
list.html
注意这里,我们想实现用户点击一个主题就能被导航到相应的邮件中。我们已经在URL和message.id之间进行了数据绑定,所以用户点击id=1的邮件就会被导航到/#/view/1。这种根据URL导航的方式也叫做深度连接,我们将会在邮件详细视图控制器中使用,以实现把一份可用的邮件链接到对应的说细视图上。
<table> <tr> <td><strong>Sender</strong></td> <td><strong>Subject</strong></td> <td><strong>Date</strong></td> </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>
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> </div> <a href='#/'>Back to message list</a>
controllers.js
为了把这些模板关联到对应控制器上,我们将给$routeProvider配置一个URL,$routeProvider将会负责调用控制器和模板。
//为核心的AMail服务创建模块 var aMailServices = angular.module('AMail', []); //在URL、模板和控制器之间建立映射关系 function emailRouteConfig($routeProvider) { $routeProvider.when('/', {controller: ListController,templateUrl:'list.html'}) //注意,为了创建详情视图,我们在id前面加了一个冒号,从而指定了一个参数化的URL组件 .when('/view/:id', {controller: DetailController, templateUrl:'detail.html'}) .otherwise({redirectTo: '/'}); } //配置我们的路由,以便AMail服务能够找到它 aMailServices.config(emailRouteConfig); //一些虚拟的邮件 messages = [{id:0,sender:'jean@somecompany.com',subject:'Hi there,old firend',date:'Dec 7,2013 12:32:00',recipients:['greg@somecompany.com'], message:'Hey,we should get together fo lunch sometime and catch up.There are many things we should collaborate on this year.'}, {id:1,sender:'maria@somecompany.com',subject:'Where did you leavemy laptop?',date:'Dec 7,2013 8:15:12',recipients:['greg@somecompany.com'], message:'I thought you were going to put it in my desk drawer.But it does not seem to be there.'}, {id:2,sender:'bill@somecompany.com',subject:'Lost python',date:'Dec 6,2013 20:35:02',recipients:['greg@somecompany.com'], message:'She doesn\'t move too fast,so just call me if you see her.'}]; //把我们的邮件发布给邮件列表模板 function ListController($scope) { $scope.messages = messages; } //从路由信息(从URL中解析出来的)中获取邮件id,然后用它找到正确的邮件对象 function DetailController($scope, $routeParams) { $scope.message = messages[$routeParams.id]; }
工程结构如下图所示:
运行结果:
点击邮件的Subject超链接,即进入相应的邮件详细信息页面,如下所示:
资料来源:《用AngularJS开发下一代Web应用》