路由器出口占位符
在本节课中,我们将学习如何使用 RouterOutlet 元素来为路由加载组件。
我们能够在应用的模板中加载 <app-home-main> 组件。然而,这并不是我们想要的效果。我们希望仅当客户端请求首页时才加载该组件。Angular Router 可以帮助我们实现这一点。首先,我们需要对模块进行一些修改。
理解路由
路由的概念是将组件与 URL 中的路径关联起来。URL 主要由域名和路径组成。
URL 还包含其他部分,但为了便于说明路由的工作原理,这里只关注路径部分。URL 的路径部分用于向服务器请求特定资源。当服务器提供我们的应用程序时,Angular 会从 URL 中提取路径,并将其与应用中注册的路由进行匹配。
Angular 不会自动知道哪个路径应该渲染哪个组件。我们必须明确告诉 Angular:当访问某个特定 URL 时,应该显示哪个组件。这个过程就是所谓的路由。
虽然不是必须为应用添加路由,但这样做有许多好处,例如:
- 将内容划分为不同的区域
- 根据特定规则保护应用的某些区域
- 更容易维护
想象一下在应用中导航。比如在一个电商网站上,你可能会点击商品、查看购物车或结账。这些操作都会带你进入不同的页面。如果构建这样的应用而没有为每个页面分配独立的 URL,将会遇到很多问题:
- 无法刷新页面并保持在当前位置。
- 无法收藏某个页面以便稍后返回。
- 无法与他人分享某个页面。
通过添加路由,这些问题就不存在了。一个 URL 可以指向应用中的特定资源。Angular 内置了路由功能,帮助我们构建自定义的 URL。
路由模块
在上一课中,我们使用 --routing 选项创建了一个模块。它生成了两个模块,其中一个名称中包含 -routing。带有 -routing 后缀的模块称为路由模块。
路由模块负责定义新路由并配置路由器。每个路由模块都与另一个模块相关联。Angular 建议路由模块的名称应与其对应的模块名称平行,并加上 -routing 后缀。
例如,如果有一个名为 home 的模块,它的路由模块应命名为 home-routing。CLI 会自动为我们添加这个后缀。
添加新路由
路由必须在路由模块中定义。我们将在 home-routing.module.ts 文件中定义第一个路由。该文件中有一个名为 routes 的变量,它被设置为一个数组。让我们将其修改为如下内容:
1import { NgModule } from '@angular/core'; 2import { Routes, RouterModule } from '@angular/router'; 3import { HomeMainComponent } from './home-main/home-main.component'; 4 5const routes: Routes = [ 6 { path: '', component: HomeMainComponent } 7]; 8 9@NgModule({ 10 imports: [RouterModule.forChild(routes)], 11 exports: [RouterModule] 12}) 13export class HomeRoutingModule { }
在 routes 数组中,我们添加了一个对象,包含两个属性。path 属性表示 URL 中的路径。空字符串等同于斜杠 /。我们正在为首页创建一条路由,因此使用空字符串是合适的。
如果地址栏中的路径与该路由的路径匹配,Angular 就会加载 component 属性指定的组件。在此例中,我们指示它加载 HomeMainComponent。
接下来,我们需要更新 HomeModule。我们将从 exports 选项中移除 HomeMainComponent。
1import { NgModule } from '@angular/core'; 2import { CommonModule } from '@angular/common'; 3 4import { HomeRoutingModule } from './home-routing.module'; 5import { HomeMainComponent } from './home-main/home-main.component'; 6 7@NgModule({ 8 declarations: [HomeMainComponent], 9 imports: [ 10 CommonModule, 11 HomeRoutingModule 12 ], 13 exports: [] 14}) 15export class HomeModule { }
我们不再导出该组件,因为当访问对应路由时,路由器将负责加载该组件。
RouterOutlet
Angular Router 提供了一个指令,作为组件的占位符。在 app.component.html 模板文件中,我们将内容替换为以下代码:
1<router-outlet></router-outlet>
<router-outlet> 是一个组件的占位符。路由器会根据当前浏览器的 URL,用与之关联的组件替换这个占位符。通过使用这个占位符,我们无需导出组件,而是可以导出模块。
我们已经修改了许多文件。让我们通过一张图来整体观察一下结构。
HomeRoutingModule 是一个路由模块,用于定义路由。我们设置了一条路由,检查客户端是否请求首页。如果是,则加载 HomeMainComponent。
home 路由模块需要被导入到某个模块中。home 模块导入了它。然后,我们在 app 模块中导入了 home 模块。在 app 组件的模板文件中,我们使用 router-outlet 指令来加载与路径注册的组件。
将这些模块连接起来后,HomeMainComponent 就会在页面上正确加载。需要注意的一点是,HomeMainComponent 不能再用于 app 组件的模板中,因为它已不再导出。现在,是由路由器通过占位符为我们加载该组件。
以下是更新后的代码:
No configuration found for ID: a786267ab068c17aaaf75313f1f87db22e07e7e279103990c2e6087d148aff68
运行示例后,可以看到 HomeMainComponent 组件能够正常渲染。