AngularJS 路由(长文解析)

AngularJS 路由:构建单页应用的导航基石

在现代前端开发中,单页应用(SPA)已经成为主流模式。用户不再需要频繁刷新页面,而是通过动态加载内容来实现流畅的交互体验。而这一切的背后,离不开一个核心机制——路由系统。AngularJS 路由正是为这类应用提供页面切换能力的重要工具。

想象一下你正在使用一个手机银行 App,点开“账户明细”后,系统不会重新加载整个页面,而是悄悄地把新内容“换”上去。这种无缝切换的体验,正是由 AngularJS 路由来实现的。它让开发者可以像搭积木一样,把不同的视图和控制器组合起来,构建出复杂但清晰的前端架构。

本文将带你一步步掌握 AngularJS 路由的核心概念,从基础配置到高级用法,涵盖实战案例与常见问题解决方案,帮助你真正理解并应用这一关键能力。


什么是 AngularJS 路由?

在传统的多页应用中,每一次页面跳转都意味着一次完整的 HTTP 请求,浏览器需要重新加载 HTML、CSS 和 JavaScript 文件。这不仅慢,还破坏了用户体验的连贯性。

AngularJS 路由的出现,就是为了打破这种“跳转即重载”的模式。它允许你在一个页面中定义多个视图(View),并通过 URL 的变化来动态切换这些视图,而无需刷新整个页面。

简单来说,AngularJS 路由就是一套“URL 到视图”的映射规则。你告诉框架:“当用户访问 /home 时,显示首页模板;访问 /about 时,展示关于页面。” 框架就会自动根据当前 URL 渲染对应的模板内容。

这就像一个智能导航系统,你输入目的地(URL),系统就自动带你到对应的位置(视图),中间过程完全透明。


安装与引入路由模块

在开始使用 AngularJS 路由之前,你需要确保项目中引入了 angular-route 模块。这个模块是 AngularJS 官方提供的路由支持库。

步骤一:引入 AngularJS 和 angular-route

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
  <!-- 引入 angular-route 模块 -->
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.min.js"></script>
</head>
<body>
  <!-- 页面内容将在此处动态插入 -->
</body>
</html>

注释:

  • angular.min.js 是核心框架文件,必须首先加载。
  • angular-route.min.js 提供了路由功能,依赖于主框架,必须在它之后引入。
  • 使用 CDN 加载是最简单的方式,适合学习和测试阶段。

步骤二:在主模块中声明依赖

// 定义主应用模块,并注入 'ngRoute' 依赖
var app = angular.module('myApp', ['ngRoute']);

注释:

  • angular.module('myApp', ['ngRoute']) 创建了一个名为 myApp 的模块,并声明它依赖于 ngRoute 模块。
  • 这一步至关重要,没有这个依赖,后续的路由配置将无法生效。

配置路由规则

一旦模块准备好,下一步就是定义路由规则。AngularJS 路由使用 .config() 方法来配置,这是模块启动时执行的配置阶段。

使用 $routeProvider 定义路径映射

app.config(['$routeProvider', function($routeProvider) {
  // 定义首页路由
  $routeProvider
    .when('/home', {
      templateUrl: 'views/home.html',  // 指定要加载的 HTML 模板
      controller: 'HomeController'     // 指定对应的控制器
    })
    // 定义关于页面路由
    .when('/about', {
      templateUrl: 'views/about.html',
      controller: 'AboutController'
    })
    // 定义默认路由(当 URL 不匹配任何规则时)
    .otherwise({
      redirectTo: '/home'  // 重定向到首页
    });
}]);

注释:

  • .when('/path', {...}) 定义一条路由规则,/path 是 URL 的路径部分。
  • templateUrl 指定要加载的 HTML 文件路径,必须是相对路径或绝对路径。
  • controller 指定该视图对应的控制器名称。
  • .otherwise({...}) 是兜底规则,当用户访问的 URL 未匹配任何 when 规则时,执行此配置。
  • redirectTo 表示重定向到指定路径。

路由路径中的参数(动态路由)

你还可以在路径中添加动态参数,比如用户 ID:

.when('/user/:id', {
  templateUrl: 'views/user.html',
  controller: 'UserController'
})

注释:

  • :id 是一个占位符,表示该位置可以接受任意值。
  • 当用户访问 /user/123 时,id 的值就是 123
  • 在控制器中可通过 $routeParams 获取该参数。

使用 ng-view 实现视图渲染

有了路由规则,还需要一个“容器”来显示动态内容。AngularJS 提供了 ng-view 指令,它负责把匹配路由的模板插入到页面中。

<div ng-view></div>

注释:

  • ng-view 是一个特殊指令,它不渲染任何内容,而是作为“占位符”。
  • 当 URL 匹配某个路由时,AngularJS 会自动把该路由配置的 templateUrl 对应的 HTML 内容插入到 ng-view 中。
  • 你可以把它想象成一个“电影屏幕”,不同路由就是不同的电影,播放时自动替换画面。

控制器与数据绑定

每个路由都应有一个对应的控制器,用于处理视图逻辑和数据。

示例:首页控制器

app.controller('HomeController', ['$scope', function($scope) {
  // 定义首页标题
  $scope.title = '欢迎来到首页';

  // 定义一个方法,用于触发页面行为
  $scope.greet = function() {
    alert('你好,欢迎使用本应用!');
  };
}]);

示例:关于页面控制器

app.controller('AboutController', ['$scope', function($scope) {
  $scope.info = '这是一个由 AngularJS 构建的单页应用示例。';
}]);

注释:

  • 控制器通过 $scope 与视图进行数据绑定。
  • $scope 是 AngularJS 中的数据上下文,所有在控制器中定义的属性和方法,都可以在模板中使用。
  • 你可以在模板中用 {{ title }}{{ info }} 直接显示数据。

路由实战:完整项目结构示例

为了更清晰地理解整个流程,下面是一个完整的项目结构:

project/
├── index.html
├── app.js
└── views/
    ├── home.html
    └── about.html

index.html

<!DOCTYPE html>
<html ng-app="myApp">
<head>
  <title>AngularJS 路由示例</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.min.js"></script>
  <script src="app.js"></script>
</head>
<body>
  <!-- 导航菜单 -->
  <nav>
    <a href="#/home">首页</a> |
    <a href="#/about">关于</a>
  </nav>

  <!-- 路由视图容器 -->
  <div ng-view></div>
</body>
</html>

views/home.html

<h2>{{ title }}</h2>
<p>这是首页内容。</p>
<button ng-click="greet()">点击问候</button>

views/about.html

<h2>关于页面</h2>
<p>{{ info }}</p>

app.js

var app = angular.module('myApp', ['ngRoute']);

app.config(['$routeProvider', function($routeProvider) {
  $routeProvider
    .when('/home', {
      templateUrl: 'views/home.html',
      controller: 'HomeController'
    })
    .when('/about', {
      templateUrl: 'views/about.html',
      controller: 'AboutController'
    })
    .otherwise({
      redirectTo: '/home'
    });
}]);

app.controller('HomeController', ['$scope', function($scope) {
  $scope.title = '欢迎来到首页';
  $scope.greet = function() {
    alert('你好,欢迎使用本应用!');
  };
}]);

app.controller('AboutController', ['$scope', function($scope) {
  $scope.info = '这是一个由 AngularJS 构建的单页应用示例。';
}]);

注释:

  • 所有文件结构清晰,便于维护。
  • 使用 # 符号的链接是 Hash 路由(#/home),这是 AngularJS 路由的默认方式,无需服务器支持。
  • 通过 ng-click 实现事件绑定,响应用户操作。

高级用法与注意事项

1. 使用 $routeParams 获取动态参数

在控制器中,你可以通过 $routeParams 获取 URL 中的动态部分:

app.controller('UserController', ['$scope', '$routeParams', function($scope, $routeParams) {
  $scope.userId = $routeParams.id;  // 获取 id 参数
  $scope.message = '用户 ID 是:' + $routeParams.id;
}]);

2. 路由守卫(路由拦截)

你可以在路由配置中添加 resolve 属性,用于在视图加载前执行异步操作(如数据获取):

.when('/profile', {
  templateUrl: 'views/profile.html',
  controller: 'ProfileController',
  resolve: {
    userData: ['$q', '$http', function($q, $http) {
      var deferred = $q.defer();
      $http.get('/api/user').then(function(res) {
        deferred.resolve(res.data);
      });
      return deferred.promise;
    }]
  }
})

注释:

  • resolve 是一个对象,每个属性都是一个异步函数。
  • 函数返回的 Promise 成功后,结果会注入到控制器中作为参数。

结语

AngularJS 路由是构建现代单页应用的基石。它让你无需刷新页面,就能实现多页面的导航体验。从基础的路径映射,到动态参数、路由守卫,它的能力足以支撑中小型项目的复杂需求。

虽然 AngularJS 已不再是最新技术,但其设计理念——尤其是路由机制——仍然值得学习。掌握它,不仅能让你理解 SPA 的核心逻辑,还能为后续学习 Angular(2+)打下坚实基础。

无论你是初学者还是中级开发者,只要动手实践一遍,你就会发现,AngularJS 路由远没有想象中那么复杂。它就像一个智能的“导航员”,默默帮你把用户带到正确的位置,而你只需关注“目的地”和“路线”本身。