Angularjs路由须要了解的那点事javascript
咱们知道angularjs是特别适合单页面应用,为了经过单页面完成复杂的业务功能,势必须要可以从一个视图跳转到另一个视图,也就是须要在单个页面里边加载不一样的模板。为了完成这个功能angularjs为咱们提供了路由服务($routeProvider)。html
先看下咱们的示例代码,html框架页index.html前端
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>angularjs路由示例</title> <script src="../../../angular.min.js"></script> <script src="../../../angular-route.js"></script> <script src="script.js"></script> <script type="text/javascript"> angular.element(document.getElementsByTagName('head')).append(angular.element('<base href="' + window.location.pathname + '" />')); </script> </head> <body ng-app="ngRouteExample"> <div ng-controller="MainController"> Choose: <a href="Book/Moby">Moby</a> | <a href="Book/Moby/ch/1">Moby: Ch1</a> | <a href="Book/Gatsby">Gatsby</a> | <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> | <a href="Book/Scarlet">Scarlet Letter</a><br/> <div ng-view></div> <hr /> <pre>$location.path() = {{$location.path()}}</pre> <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre> <pre>$route.current.params = {{$route.current.params}}</pre> <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre> <pre>$routeParams = {{$routeParams}}</pre> </div> </body> </html>
script.js文件的内容html5
(function(angular) {
'use strict';
angular.module('ngRouteExample', ['ngRoute'])
.controller('MainController', function($scope, $route, $routeParams, $location) {
$scope.$route = $route;
$scope.$location = $location;
$scope.$routeParams = $routeParams;
// $scope.$on('$routeChangeSuccess', function(evt, next, previous) {
// debugger;
// });
})
.controller('BookController', function($scope, $routeParams) {
$scope.name = "BookController";
$scope.params = $routeParams;
})
.controller('ChapterController', function($scope, $routeParams) {
$scope.name = "ChapterController";
$scope.params = $routeParams;
})
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/Book/:bookId', {
templateUrl: 'book.html',
controller: 'BookController',
resolve: {
// I will cause a 1 second delay
delay: function($q, $timeout) {
var delay = $q.defer();
$timeout(delay.resolve, 1000);
return delay.promise;
}
}
})
.when('/Book/:bookId/ch/:chapterId', {
templateUrl: 'chapter.html',
controller: 'ChapterController'
});
// configure html5 to get links working on jsfiddle
$locationProvider.html5Mode(true);
});
})(window.angular);
book.htmljava
controller: {{name}}<br /> Book Id: {{params.bookId}}<br />
chapter.htmlangularjs
controller: {{name}}<br /> Book Id: {{params.bookId}}<br /> Chapter Id: {{params.chapterId}}
1、为何是单页应用promise
angularjs做为前端mvc框架,其页面中功能的切换势必得在URL上有所体现,可是其又不能刷新页面向服务器发送请求,由于每一个请求须要对应服务器端的一个页面或者某个控制器的Action,也就是angularjs须要依赖服务器端的mvc框架,这样angularjs做为前端mvc框架就不那么纯粹了。浏览器
直接刷新angularjs的url,服务器找不到资源,具体效果以下服务器
那怎么解决这个问题呢?这就须要服务器能够将这个路由重定向到index.html页面,并将/Book/Moby做为url参数返回,而后在页面中在路由到/Book/Moby便可。mvc
2、页面初始化显示某个特定模板
通常状况下index.html是一个框架模板,不会包含具体的业务功能,具体页面效果以下
咱们选中 Moby,在页面中间显示出来book.html的内容了,咱们能够看到url地址已经变了,页面的效果以下
实际的开发中,咱们每每不能只显示框架页index.html的内容,而是显示上图相似的效果,那咱们怎么办呢?其实咱们只须要页面加载完直接将原来的url切换为/Book/Moby便可,具体代码
.controller('MainController', function($scope, $route, $routeParams, $location) {
$scope.$route = $route;
$scope.$location = $location;
$scope.$routeParams = $routeParams;
// $scope.$on('$routeChangeSuccess', function(evt, next, previous) {
// debugger;
// });
//控制器执行完毕,路由到/Book/Moby
$location.path("/Book/Moby");
})
3、无刷新切换路由
其实仔细想一想,上边切换url是须要依赖无刷新切换路由的,即url变了,加载了相应的模板,可是框架模板页index.html却没有刷新。为了实现这个功能,angularjs针对新旧浏览器提供了两种方式,
针对老式浏览器可使用标签模式,针对现代浏览器可使用HTML5模式。
前者在URL中使用#来防止页面刷新,同时造成浏览器历史记录。具体形式以下
http://yoursite.com/#!/inbox/all
AngularJS支持的另一种路由模式是 html5 模式。在这个模式中,URL看起来和普通的URL
同样(在老式浏览器中看起来仍是使用标签的URL)。例如,一样的路由在HTML5模式中看起来
是这样的:
http://yoursite.com/inbox/all
在AngularJS内部, $location 服务经过HTML5历史API让应用可以使用普通的URL路径来
路由。当浏览器不支持HTML5历史API时, $location 服务会自动使用标签模式的URL做为替代
方案。
二者之间的切换经过$locationProvider.html5Mode进行切换。