实际的项目中,很少只有一个模块的。我们当前的学习项目后期也要添加班级管理、学生管理、课程管理等其它的模块。那么当前的我们使用[http://localhost:4200/](http://localhost:4200/)来访问教师列表便显得不合适了。我们希望的是得到如下链接: | 地址 | 功能描述 | | ---- | ---- | | <空> | 首页,提供页面导航功能及欢迎信息 | | `teacher` | 教师列表 | | `teacher/add` | 添加新教师 | | `teacher/edit/<id>` | 编辑教师 | | `klass` | 班级列表 | | `klass/add` | 添加班级 | | `klass/edit/<id>` | 编辑班级 | 按照上述设计,重新对路由进行规划,如下: app-routing.module.ts ``` const routes: Routes = [ { path: 'teacher', component: TeacherIndexComponent }, { path: 'teacher/add', component: TeacherAddComponent }, { path: 'teacher/edit/:id', component: TeacherEditComponent } ]; ``` 同时,我们为首页增加一个教师管理的快捷方式: app.component.html ``` <h2>欢迎使用河北工业大学教务管理系统</h2> <ul> <li><a routerLink="">首页</a></li> <li><a routerLink="teacher">教师管理</a></li> </ul> <router-outlet></router-outlet> ``` # 测试 ![](https://img.kancloud.cn/29/bf/29bf66abfae11ffe5aed20951cdc8d95_742x353.gif) 通过测试我们发现如下`bug`: * [ ] 点击编辑按钮控制台报错。 * [ ] 新增完成后跳转到了首页,而非教师列表页。 ## Cannot match any routes. 点击编辑按钮后,显示了`Cannot match any routes. URL Segment: 'edit/3'`错误,提示未能成功匹配路由。的确如此,我们更新路由,原来的`edit/3`已完变更为`teacher/edit/3`了。但问题是:为什么`新增`按钮是有效的,而没有提示不能匹配`add`呢?我们把两外的代码比较一下: teacher-index.component.html ```html <a routerLink="./add">新增</a> <td><a [routerLink]="['/edit', teacher.id]">编辑</a> ``` 通过比较代码,我们猜测问题可能出现在两点上: * 使用`routeLink`的不报错而使用了`[routerLink]`则会报错。 * 使用`"./add"`不报错而使用`'/edit'`报错。 有了猜测的方向后开始进行尝试: 验证猜测一: ``` <a [routerLink]="['./add']">新增</a> <td><a [routerLink]="['/edit', teacher.id]">编辑</a> ``` 测试后我们发现新增仍然生效,而编辑则仍然报错。得出结论:猜测一错误。 验证猜测二: ``` <a [routerLink]="['./add']">新增</a> <td><a [routerLink]="['./edit➊', teacher.id]">编辑</a> ``` * ➊ 由原`/edit`变为`./edit`。 保存代码后进行测试,编辑按钮正常。结论:猜测二正确。 ## 绝对地址与相对地址 以前我们学习过:相对地址是相对于当前路径的,而绝对地址则是相对于根路径的。在`angular`中略有不同,由于`angular`使用的`路由`机制,所以在`angular`中,相对地址是相对于当前`路由`的,而绝对地址则是相对于`根路由`的。在我们的当前的项目中,由于`根路由`为空所以才**看似**是相对于`根路径`的。 我们知道`/edit`为绝对地址(路由),而`./edit`为相对地址(路由)。 所以当`routeLink`设置为`/edit`时,`angular`会尝试找`path`为`edit`的路由,该路由不存在所以控制台报错。而当`routeLink`设置为`./edit`时,表示相对于当前路由,此时当前路由`pah` = `teacher`,所以`angular`会尝试找中径对应`teacher/edit`的路由,进而进行了成功的跳转。 ## C层中的导航 按刚刚学习的理论,我们打开教师新增组件的C层中的跳转代码: teacher-add.component.ts ``` this.router.navigate(['./']); ``` 我们发现:我们在参数中维护为`./`而非`/`,如果`./`代表相对路由,则跳转的地址应该是自己(`./ 当前地址`),但为何新增完成了跳转到了首页,而非我们所期望的列表页呢?这是由于`router.navigate`方法默认跳转的就是绝对路径,如果想让其跳转到相对路径,需要这样使用: ``` constructor(private httpClient: HttpClient, private appComponent: AppComponent, private router: Router, ➊ private route: ActivatedRoute ➊) { } ... this.router.navigate(['./'], {relativeTo: this.route}); ➋ ``` * ➊ Router:路由者,提供路由功能;ActivatedRoute:被激活的路由,提供路由状态。 * ➋ `navigate(array, {})`,接收的第二个参数为对象,对象中的属性`relativeTo`规定了跳转的相对路由。 此时,我们完成添加后点击保存就不会跳转到首页了,我们的目标是让其跳转到教师列表,则需要修正为: ``` this.router.navigate(['./../'➊], {relativeTo: this.route}); ``` * ➊ `./`当前路径 `../`上级路径,`./../`当前路径的上级路径。当前路径为`teacher/add`时,当前路径的上级路径为`teacher`。 * # 本节小测 按上述理论**自行完成编辑组件的路由跳转修改** # 参考文档 | 名称 | 链接 | 预计学习时长(分) | | --- | --- | --- | | 相对导航 | [https://www.angular.cn/guide/router#relative-navigation](https://www.angular.cn/guide/router#relative-navigation) | 5 | | 源码地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step2.6.3](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step2.6.3) | - |