[从 0 开始的 Angular 生活]No.38 实现一个 Angular Router 切换组件页面(一)

前言

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

需求

需求大概是这样的:

  • 开一个新的 Angular 项目,并且一开始选择加入 Router 功能

    • 根组件是 AppComponent ,然后下方有三个子组件分别是

      • page1
      • page2
      • page3
    • 可以在 AppComponent 内点击连结切换到这三个页面

参考文档:

建立环境

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

观察文件结构

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

12345678910
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 这只文件给引入了。

123456789101112131415161718
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 数据夹内多了 app-routing.module.ts 这只文件。

运行结果

没有什么明显的变化。

分别建立三个组件

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

  • page1
  • page2
  • page3

ng g c page1

配置路由

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

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

加入 RouterLink 连结

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

对 Appcomponent 进行 Template 上的调整

12345678910111213
<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 的模式吧

123
.active{  color: red;}

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

注册路由器与路由定义

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

  • path - 切换到这个组件的路径
  • component - 切换的组件名称
12345678910111213141516171819
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 进行首次导航。

存档,试着运行看看。

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

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

设置万用符与缺省路由

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

  • 如果在地址栏随意输入会跳出错误

    • 而使用者是这么白目
  • 需要设定一组缺省路由,也就是使用者初次进入网页时会显示的画面

设置万用符

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

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

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

因此修改 app-routing.module

1234567891011121314151617181920
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 { }

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

设置缺省路由

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

123456789101112131415161718192021
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

顺序错误的场合

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

1234567
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 - 范例源代码

原文地址:https://www.cnblogs.com/lijianming180/p/12014093.html

时间: 2024-10-10 03:10:14

[从 0 开始的 Angular 生活]No.38 实现一个 Angular Router 切换组件页面(一)的相关文章

Angular项目构建指南 - 不再为angular构建而犹豫不决(转)

如果你不知道什么是Angular或者根本没听说过,那么我接下来所说的对你来说毫无益处,不过如果你打算以后会接触Angular或者干脆要涨涨姿势~读下去还是有点用的. Angular和它之前所出现的其余前端框架最大的不同,在于它的核心不再是DOM,而是数据,是model.我们惯用的不管是单纯的jQuery还是MVC的Backbone,它们本质仍是让我们更方便更有条理的操作DOM,但是Angular不是.通过一系列魔术般的手法,它将一切的重心转移到数据上.以开发应用而不是操作节点的方式去开发Web,

[Angular] Bind async requests in your Angular template with the async pipe and the &quot;as&quot; keyword

Angular allows us to conveniently use the async pipe to automatically register to RxJS observables and render the result into the template once the request succeeds. This has some drawbacks, especially if we want to bind the same data in multiple par

angular核心原理解析1:angular自启动过程

angularJS的源代码整体上来说是一个自执行函数,在angularJS加载完成后,就会自动执行了. angular源代码中: angular = window.angular || (window.angular = {}) 定义一个全局的angular空对象. 然后: bindJQuery(); //绑定jQuery publishExternalAPI(angular); //扩展angular对象的方法和属性 jqLite(document).ready(function() { an

warning MSB3162: 所选的“Microsoft Report Viewer 2012 Runtime”项需要“Microsoft.SqlServer.SQLSysClrTypes.11.0”。在“系统必备”对话框中选择缺少的系统必备组件,或者为缺少的系统必备组件创建引导程序包。

warning MSB3162: 所选的"Microsoft Report Viewer 2012 Runtime"项需要"Microsoft.SqlServer.SQLSysClrTypes.11.0".在"系统必备"对话框中选择缺少的系统必备组件,或者为缺少的系统必备组件创建引导程序包. 发布ReportViewer程序遇到这个问题. 到处查了下,发现解决方法是这样的. 1)打开这个路径下的xml文件: C:\Program Files (x

angular在ie8下的一个bug

昨天拿项目在ie8下测试,发现不少bug,其中有一个bug让我很不解,报了一个thead开头的bug,因为已经切回到linux下了,我就不报具体是什么bug了,鼓捣了半天,发现引用angular的应用中,table元素在ie8或者7下不能缺少thead,即便是空,也得加上空的thead. angular在ie8下的一个bug,布布扣,bubuko.com

Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器

Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器 MVC概念 MVC的含义是 “模型-视图-控制器”.MVC是一个架构良好并且易于测试和易于维护的开发模式.基于MVC模式的应用程序包含: · Models: 表示该应用程序的数据并使用验证逻辑来强制实施业务规则的数据类. · Views: 应用程序动态生成 HTML所使用的模板文件. · Controllers: 处理浏览器的请求,取得数据模型,然后指定要响应浏览器请求的视图模板. 本系列教程,我们将覆盖所有这些概念,并告诉

从11.2.0.2开始,数据库补丁包是一个完整安装包(转)

从11.2.0.2开始,数据库补丁包是一个完整安装包.也就是说:比如要打11.2.0.2的补丁包,直接用11.2.0.2包来安装就可以了,不需要像10G一样先安装数据库软件再来打补丁包. 如果已经安装了11.2.0.1的用户也可以像10G一样打补丁包,也可以把11.2.0.2安装到新目录,安装好以后,再把老的数据库数据迁移过去.oracle说的“In-Place Upgrade与Out-of-Place Upgrade” 还有下载补丁包的时候要注意一点是,分7个包,每个包包含不同的应用系统: I

爱搜索,爱生活,基于豆瓣API &amp; Angular开发的web App(by vczero)

一.扯淡的说 name:[豆瓣搜索] 最近关注了下豆瓣的API,发现豆瓣开放平台需要加强API文档撰写啊....但是有个可喜的发现豆瓣V2接口提供了搜索接口.最近在用phantom弄些爬虫,想想,真是美丽极了!有个豆瓣的接口,我都不用去爬数据,不用数据存储,丢给github page直接完事.豆瓣,Nice!最近也在看angular,于是就萌生了使用Angular + 豆瓣API 做一个web app.于是...网上回家就折腾了. 体验地址:http://vczero.github.io/t/h

从0开始的LeetCode生活—461-Hamming Distance(汉明距离)

题目: The Hamming distance between two integers is the number of positions at which the corresponding bits are different. Given two integers x and y, calculate the Hamming distance. Note: 0 ≤ x, y < 231. Example: Input: x = 1, y = 4 Output: 2 Explanati