本网站只能被运行在支持JavaScript脚本的环境中

第八节 模板与路由管理

准备Web服务器

当尝试使用本节示例时,由于浏览器安全限制,需要从Web服务器访问页面。

使用ngRoute模块管理路由

当从AngularJS官网下载开发包后,在angular.min.js文件所在文件夹内,包含angular-route.min.js了脚本文件,当使用ngRoute模块管理路由时,首先需要引用该脚本文件。

简单使用示例

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS示例页面</title>
<script src="angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script>
angular.module("myApp", ["ngRoute"])
.config(function($routeProvider){
    $routeProvider
    .when('/',{
        controller:'RootController',
        templateUrl:'root.html'
    });
})
.controller("RootController",function($scope) {
    $scope.message = 'message by RootController.';
}); 
</script>
<style>
.border {
    border: 1px solid red;
}
</style>
</head>
<body>
<h1>sample.html</h1>
<div ng-view class="border"></div>
</body>
</html> 

root.html文件中的内容

<h1>Root Template</h1>
<p>{{message}}</p>

在Web服务器中访问sample.html页面文件。

显示结果

在sample.html页面中将读取root.html文件中的内容并通过ng-view内部指令将其添加到DOM中。

说明

通过如下所示的代码调用ngRoute模块。

<script src="angular.min.js"></script>
<script src="angular-route.min.js"></script>
...
angular.module("myApp", ["ngRoute"])

在这段代码中首先引用angular.min.js脚本文件。同时在定义myApp模块时加载ngRoute模块。

通过如下所示的代码定义视图。

<div ng-view class="border"></div>

ng-view内置指令用于定义视图,视图来源将在脚本代码中进行指定,代码如下所示。

.config(function($routeProvider){
    $routeProvider
    .when('/',{
        controller:'RootController',
        templateUrl:'root.html'
    });
})

这段代码通过模块的config方法对模块进行配置,同时将$routeProvider指定为配置函数的参数。

在$routeProvider的when方法中,指定各URL所读取的视图模板来源及使用控制器。

在root.html文件所定义的视图中,显示一个字符串,代码如下所示:

<h1>Root Template</h1>
<p>{{message}}</p>

该字符串在控制器中进行定义,代码如下所示:

.controller("RootController",function($scope) {
    $scope.message = 'message by RootController.';
});

页面切换

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS示例页面</title>
<script src="angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script>
angular.module("myApp", ["ngRoute"])
.config(function($routeProvider){
    $routeProvider
    .when('/', {
        templateUrl: 'first.html'
    })
    .when('/next', {
        templateUrl: 'second.html'
    })
    .otherwise({
        templateUrl: 'not-found.html'
    });
}); 
</script>
<style>
.border {
    border: 1px solid red;
    padding: 0 0 10px 10px;
}
</style>
</head>
<body>
<h1>sample.html</h1>
<div ng-view class="border"></div>
</body>
</html>

first.html文件中的内容

<h1>First Page</h1>
<a href="#/next">next</a>

second.html文件中的内容

<h1>Second Page</h1>
<a href="#/">back</a>
<a href="#/aaaa">not found</a>

not-found.html文件中的内容

<h1>Page Not Found</h1>

画面显示

点击next链接之后

点击not found链接之后

$routeProvider的when()函数可以为一个方法链。

在页面中需指定Hashbang格式的URL(在URL之前添加#符号)。

可以在otherwise方法中指定其他所有URL使用的默认视图来源及控制器。

使用URL参数

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS示例页面</title>
<script src="angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script>
angular.module("myApp", ["ngRoute"])
.config(function($routeProvider){
    $routeProvider
    .when('/:param', {
        templateUrl: 'sub.html',
        controller:function($scope,$routeParams){
            $scope.paramValue=$routeParams.param;
        }
    });
}); 
</script>
<style>
.border {
    border: 1px solid red;
    padding: 0 0 10px 10px;
}
</style>
</head>
<body>
<h1>sample.html</h1>
<div ng-view class="border"></div>
</body>
</html>

sub.html文件中的内容

<h1>param = {{paramValue}}</h1>

从浏览器访问http://localhost/sample.html#/hoge。

画面显示

如果通过$routeProvider定义路由的时候采用:<参数名>这种形式,则可以在控制器中获取该参数值。

在控制器中添加使用$routeParams指令,则可以通过$routeParams.<参数名>来获取参数值。

不使用Hashbang

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>AngularJS示例页面</title>
<base href="/">
<script src="angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script>
angular.module("myApp", ["ngRoute"])
.config(function($routeProvider,$locationProvider){
    $locationProvider.html5Mode(true);
    $routeProvider
    .when('/hoge', {
        templateUrl: 'template.html'
    });
}); 
</script>
<style>
.border {
    border: 1px solid red;
    padding: 0 0 10px 10px;
}
</style>
</head>
<body>
<a href="hoge">/hoge</a>
<div ng-view class="border"></div>
</body>
</html> 

template.html文件中的内容

<h1>Template</h1>

画面显示

点击页面中的链接

如果不想使用Hashbang格式,可以通过使用$locationProvider的html5Mode方法并且将方法所使用参数值设为true的方法来调用HTML 5的pushState方法来替换URL:

如果使用HTML 5模式,需要在head标签中指定基准URL,代码如下所示:

<base href="/">

可以通过在html5Mode方法中将requireBase属性值设置为false的方法来避免设置基准URL,代码如下所示。

$locationProvider.html5Mode({
    enabled:true,
    requireBase: false
});

但是,在点击链接后将页面刷新的话,会产生404页面错误,所以需要设置mode_rewrite。

动态修改页面标题

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title ng-bind="title + ' - Sample'"></title>
<script src="angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script>
angular.module("myApp", ["ngRoute"])
.config(function($routeProvider){
    $routeProvider
    .when('/', {
        title:'Top Page',
        template: '<h1>top</h1>'
    })
    .when('/hoge',{
        title:'Hoge Page',
        template: '<h1>hoge</h1>'
    });
})
.run(function($rootScope){
    $rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
        $rootScope.title = current.$$route.title;
    });
}); 
</script>
<style>
.border {
    border: 1px solid red;
    padding: 0 0 10px 10px;
}
</style>
</head>
<body>
<a href="#/hoge">/hoge</a>
<div ng-view class="border"></div>
</body>
</html>

画面显示

点击页面链接

首先在title标签中使用ng-bind指令绑定默认标题。

然后在使用$routeProvider定义路由时,在when()方法的参数中指定路由对象的title属性值。

在模块的run方法中,使用$rootScope.$on方法监听页面URL的成功修改事件($routeChangeSuccess),并且在事件回调函数中修改页面标题。

获取URL信息

<!doctype html>
<html ng-app="myApp"> 
<head>
<title>Node app</title>
<script src="angular.js"></script>
<script>
angular.module('myApp', []) 
.controller('SampleController',function($location, $filter){
    var str = 'absUrl() = ' + $location.absUrl() + '\r\n'
            + 'url() = ' + $location.url() + '\r\n'
            + 'protocol() = ' + $location.protocol() + '\r\n'
            + 'host() = ' + $location.host() + '\r\n'
            + 'port() = ' + $location.port() + '\r\n'
            + 'path() = ' + $location.path() + '\r\n'
            + 'search() = ' + $filter('json')($location.search()) + '\r\n'
            + 'hash() = ' + $location.hash() + '\r\n';
    console.log(str);
});
</script>
</head>
<body ng-controller="SampleController">
</body>
</html>

当访问http://localhost/sample.html#/hoge/fuga?name=HOGE#hashValue地址时,浏览器控制台输出结果

$location对象内部封装了window.location对象。

$location对象具有几个setter()方法($location.path('piyo'))。

操作Cookie

<!DOCTYPE HTML>
<html ng-app="myApp">
<head>
<script src="angular.min.js"></script>
<script src="angular-cookies.min.js"></script>
<script>
var myApp = angular.module('myApp', ['ngCookies']);
myApp.run(function($cookieStore) {
    $cookieStore.put('hoge', {name: 'HOGE'});
})
.controller('SampleController', function($scope, $cookieStore) {
    $scope.value = $cookieStore.get('hoge');
});
</script>
</head>
<body ng-controller="SampleController">
<pre>{{value | json}}</pre>
</body>
</html>

页面显示

可以通过ngCookies模块的使用来简单操作Cookie。