zoukankan      html  css  js  c++  java
  • [从 0 开始的 Angular 生活]No.38 实现一个 Angular Router 切换组件页面(一)

    前言

    今天是进入公司的第三天,为了能尽快投入项目与成为团队可用的战力,我正在努力啃官方文档学习 Angular 的知识,所以这一篇文章主要是记录我如何阅读官方文档后,实现这个非常基本的、带导航的网页应用。

    需求

    需求大概是这样的:

    • 开一个新的 Angular 项目,并且一开始选择加入 Router 功能
      • 根组件是 AppComponent ,然后下方有三个子组件分别是
        • page1
        • page2
        • page3
      • 可以在 AppComponent 内点击连结切换到这三个页面

    参考文档:

    建立环境

    输入 ng new ngRouterDemo 建立新项目,并直接选择要使用 Router 。

    观察文件结构

    这次选择加入 Router 后,发现 app 数据夹内多了 app-routing.module.ts

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';

    const routes: Routes = [];

    @NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
    })
    export class { }

    然后 app.module.ts 中也把 app-routing.module.ts 这只文件给引入了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';

    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';

    @NgModule({
    declarations: [
    AppComponent
    ],
    imports: [
    BrowserModule,
    AppRoutingModule
    ],
    providers: [],
    bootstrap: [AppComponent]
    })
    export class { }

    对照一下有无加入 Router 的部分

    app.module

    除此之外就是 app 数据夹内多了 app-routing.module.ts 这只文件。

    运行结果

    没有什么明显的变化。

    分别建立三个组件

    输入命令建立本次范例用的组件

    • page1
    • page2
    • page3

    ng g c page1

    配置路由

    因为是选择使用 Router 的模式,所以 Angular CLI 缺省帮我们加入了 router-outlet 标签,这代表路由切换后的画面都会在这个标签里面呈现。

    以下引用自官方说明:
    RouterOutlet 是一个来自路由模块中的命令,它的用法类似于组件。 它扮演一个占位符的角色,用于在模板中标出一个位置,路由器将会把要显示在这个出口处的组件显示在这里。
    有了这份配置,当本应用在浏览器中的 URL 变为 /heroes 时,路由器就会匹配到 path 为 heroes 的 Route,并在宿主检视中的 RouterOutlet 之后显示 HeroListComponent 组件。

    因为要点击连结后透过路由配置切换到该组件,所以必须先设置路由器连结 (Router links):

    对 Appcomponent 进行 Template 上的调整

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <h1>点击以下连结切换组件</h1>
    <ul>
    <li>
    <a routerLink="/page1" routerLinkActive="active">Page1</a>
    </li>
    <li>
    <a routerLink="/page2" routerLinkActive="active">Page2</a>
    </li>
    <li>
    <a routerLink="/page3" routerLinkActive="active">Page3</a>
    </li>
    </ul>
    <router-outlet></router-outlet>

    • RouterLink
      • a 标签上的 RouterLink 命令让路由器得以控制这个 a 元素,这里的导航路径是固定的,因此可以把一个字符串赋给 routerLink(”一次性”绑定)。
      • 这后面接的就是实际上地址栏显示的路径
    • RouterLinkActive
      • 在每个 a 标签上,你会看到一个 RouterLinkActive 的属性绑定,像是 routerLinkActive="..."
      • 等号右边可以填入包含一些用空格分隔的 CSS 类名,当这个连结启用时,路由器将会把它们加上去
        • 并在处于非活动状态时移除

    为了方便辨识效果,所以也加入 .active 的模式吧

    1
    2
    3
    .active{
    color: red;
    }

    这边要注意的是 CSS 模式要写在 Appcomponent 内。

    注册路由器与路由定义

    要使用路由的话,必须要把要使用的组件 import 进来,并且在 routes 数组内配置它们,数组内传入一个对象,而对象内可以传入参数:

    • path - 切换到这个组件的路径
    • component - 切换的组件名称
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    import { Page1Component } from './page1/page1.component';
    import { Page2Component } from './page2/page2.component';
    import { Page3Component } from './page3/page3.component';

    const routes: Routes = [ 大专栏  [从 0 开始的 Angular 生活]No.38 实现一个 Angular Router 切换组件页面(一)
    { path: 'page1', component: Page1Component },
    { path: 'page2', component: Page2Component },
    { path: 'page3', component: Page3Component },
    ];

    @NgModule({
    imports: [
    RouterModule.forRoot(routes, { enableTracing: true })
    ],
    exports: [RouterModule]
    })
    export class AppRoutingModule { }

    当我们定义好路由数组 routes 并把它传给 RouterModule.forRoot() 方法后:

    • 它会返回一个模块,其中包含配置好的 Router 服务提供商,以及路由库所需的其它提供商。

    一旦激活了应用 Router 就会根据当前的浏览器 URL 进行首次导航。

    存档,试着运行看看。

    page1

    page2

    这样基础的 Angular 路由范例就完成了!

    而因为我们有在 RouterModule.forRoot() 把 enableTracing 打开,所以当切换路由时时可以看到一些额外消息:

    设置万用符与缺省路由

    虽然我们基础的范例完成了但还不够好,因为:

    • 如果在地址栏随意输入会跳出错误
      • 而使用者是这么白目
    • 需要设定一组缺省路由,也就是使用者初次进入网页时会显示的画面

    设置万用符

    新增一个万用符路由来拦截所有无效的 URL 并处理它们。 万用符路由的 path 是两个星号(**),它会匹配任何 URL。 当路由器匹配不上以前定义的那些路由时,它就会选择这个路由。

    万用符路由可以导航到自订的 “404 Not Found” 组件,也可以重定向到一个现有路由。

    特别要注意的是:
    路由器使用先匹配者优先的策略来选择路由,万用符路由是路由配置中最没有特定性的那个,因此务必确保它是配置中的最后一个路由。

    因此修改 app-routing.module

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    import { Page1Component } from './page1/page1.component';
    import { Page2Component } from './page2/page2.component';
    import { Page3Component } from './page3/page3.component';

    const routes: Routes = [
    { path: 'page1', component: Page1Component },
    { path: 'page2', component: Page2Component },
    { path: 'page3', component: Page3Component },
    { path: '**', component: Page1Component },
    ];

    @NgModule({
    imports: [
    RouterModule.forRoot(routes, { enableTracing: true })
    ],
    exports: [RouterModule]
    })
    export class AppRoutingModule { }

    胡乱输入路径

    像这样,永远确保万用符在最后一组路由就可以了,而且也不会跳错误。

    设置缺省路由

    与设置万用符时差不多,由于路由是有顺序性的,因此应该其放在万用符路由的前一个。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import { NgModule } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    import { Page1Component } from './page1/page1.component';
    import { Page2Component } from './page2/page2.component';
    import { Page3Component } from './page3/page3.component';

    const routes: Routes = [
    { path: 'page1', component: Page1Component },
    { path: 'page2', component: Page2Component },
    { path: 'page3', component: Page3Component },
    { path: '', redirectTo: 'page2', pathMatch: 'full' },
    { path: '**', component: Page1Component },
    ];

    @NgModule({
    imports: [
    RouterModule.forRoot(routes, { enableTracing: true })
    ],
    exports: [RouterModule]
    })
    export class AppRoutingModule { }

    为了方便辨识,我将缺省路由设置为 page2 ,也就是预期当使用者初次进入网站时会看到这个画面。

    重定向路由需要一个 pathMatch 属性,来告诉路由器如何用 URL 去匹配路由的路径,否则路由器就会报错。

    在本范例中路由器应该只有在完整的 URL 等于 ‘’ 时才选择 Page2Component 组件,因此要把 pathMatch 设定为 ‘full’。

    可以观察下方的 log ,发现一开始如果网址都没输入时,会自动跳转到 page2

    顺序错误的场合

    前面提到路由器使用先匹配者优先的策略来选择路由,所以顺序很重要,如果把万用符的顺序稍微挪动,如:

    1
    2
    3
    4
    5
    6
    7
    const routes: Routes = [
    { path: 'page1', component: Page1Component },
    { path: 'page2', component: Page2Component },
    { path: 'page3', component: Page3Component },
    { path: '**', component: Page1Component },
    { path: '', redirectTo: 'page2', pathMatch: 'full' },
    ];

    路由顺序调换

    因为匹配到的路由会变成万用符的路由,因此就不会跳转到 page2 了。

    小结

    透过实现这个非常基本的、带导航的网页应用学到了如何:

    • 载入路由库
    • 在根组件的 Template 中新增一个导览列,导览列中有一些 A 标签、routerLink 命令和 routerLinkActive 命令
    • 在根组件的 Template 中新增一个 router-outlet 命令,页面将会被显示在那里
    • 用 RouterModule.forRoot 配置路由器模块
    • 使用万用符路由来处理无效路由
    • 当应用在空路径下激活时,导航到缺省路由

    • GitHub - 范例源代码

  • 相关阅读:
    构建之法阅读笔记02
    学习进度
    构建之法阅读笔记01
    小学生的四则运算题
    构建之法----速读问题
    软件工程概论作业一
    分数 任意输入
    JAVA异常
    大道至简——第七、八章读后感
    super 要点
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12014093.html
Copyright © 2011-2022 走看看