Angularjs路由需要了解的那点事

我们知道angularjs是特别适合单页面应用,为了通过单页面完成复杂的业务功能,势必需要能够从一个视图跳转到另外一个视图,也就是需要在单个页面里边加载不同的模板。为了完成这个功能angularjs为我们提供了路由服务($routeProvider)。

先看下我们的示例代码,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文件的内容

(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.html

controller: {{name}}<br />
Book Id: {{params.bookId}}<br />

chapter.html

controller: {{name}}<br />
Book Id: {{params.bookId}}<br />
Chapter Id: {{params.chapterId}}

一、为什么是单页应用

angularjs作为前端mvc框架,其页面中功能的切换势必得在URL上有所体现,但是其又不能刷新页面向服务器发送请求,因为每个请求需要对应服务器端的一个页面或者某个控制器的Action,也就是angularjs需要依赖服务器端的mvc框架,这样angularjs作为前端mvc框架就不那么纯粹了。

直接刷新angularjs的url,服务器找不到资源,具体效果如下

那怎么解决这个问题呢?这就需要服务器可以将这个路由重定向到index.html页面,并将/Book/Moby作为url参数返回,然后在页面中在路由到/Book/Moby即可。

二、页面初始化显示某个特定模板

一般情况下index.html是一个框架模板,不会包含具体的业务功能,具体页面效果如下