Angular官网教程示例知识点总结

1.背景

在我开始自学Angular的时候,是直接看的Angular的中文官网:
https://angular.cn
官网讲得非常细致,非常专业。其中有个“英雄指南”的示例,我觉得拿来实际操作一番,会学到非常多的东西,如下图:
在这里插入图片描述
下文就是把我当时在这个示例中所学到的知识点,全部总结出来,供大家参考。

2.知识点

2.1 应用的外壳

2.1.1 使用 Angular CLI 创建初始的应用结构

ng new angular-tour-of-heroes

2.1.2 启动应用服务器

cd angular-tour-of-heroes
ng serve --open

2.1.3 双花括号表达式

<h1>{{title}}</h1>

双花括号语法是 Angular 的插值绑定语法。 这个插值绑定的意思是把组件的 title 属性的值绑定到 HTML 中的 h1 标记中。

2.2 英雄编辑器

2.2.1 使用 Angular CLI 创建一个名为 heroes 的新组件

ng generate component heroes
CLI 创建了一个新的文件夹 src/app/heroes/,并生成了 HeroesComponent 的三个文件。

2.2.2 @Component装饰器函数

@Component() 装饰器表明紧随它的那个类是一个组件,并提供模板和该组件专属的元数据。

2.2.3 元数据属性

CLI 会自动生成了三个元数据属性:

  1. selector— 组件的选择器(CSS 元素选择器)
  2. templateUrl— 组件模板文件的位置。
  3. styleUrls— 组件私有 CSS 样式表文件的位置。

CSS 元素选择器 app-heroes 用来在父组件的模板中匹配 HTML 元素的名称,以识别出该组件。

  • selector:是一个 CSS 选择器,它会告诉 Angular,一旦在模板 HTML中找到了这个选择器对应的标签,就创建并插入该组件的一个实例。 比如,如果应用的 HTML 中包含,Angular 就会在这些标签中插入一个 HeroListComponent 实例的视图。
  • templateUrl:该组件的 HTML 模板文件相对于这个组件文件的地址。另外,你还可以用 template 属性的值来提供内联的 HTML 模板。 这个模板定义了该组件的宿主视图。
  • providers:当前组件所需的服务提供商的一个数组。在这个例子中,它告诉 Angular 该如何提供一个 HeroService实例,以获取要显示的英雄列表。

2.2.4 生命周期钩子

ngOnInit 是一个生命周期钩子,Angular 在创建完组件后很快就会调用 ngOnInit。这里是放置初始化逻辑的好地方。
始终要 export 这个组件类,以便在其它地方(比如 AppModule)导入它。

2.2.5 管道

<h2>{{hero.name | uppercase}} Details</h2> 

浏览器刷新了。现在,英雄的名字显示成了大写字母。
绑定表达式中的 uppercase 位于管道操作符( | )的右边,用来调用内置管道 UppercasePipe。
管道 是格式化字符串、金额、日期和其它显示数据的好办法。 Angular 发布了一些内置管道,而且你还可以创建自己的管道。

2.2.6 双向数据绑定

[(ngModel)] 是 Angular 的双向数据绑定语法。
这里把 hero.name 属性绑定到了 HTML 的 textbox 元素上,以便数据流可以双向流动:从 hero.name 属性流动到 textbox,并且从 textbox 流回到 hero.name 。

2.2.7 AppModule

Angular 需要知道如何把应用程序的各个部分组合到一起,以及该应用需要哪些其它文件和库。 这些信息被称为元数据(metadata)。
有些元数据位于 @Component 装饰器中,你会把它加到组件类上。 另一些关键性的元数据位于 @NgModule 装饰器中。
最重要的 @NgModule 装饰器位于顶级类 AppModule 上。

2.3 显示英雄列表

2.3.1 复写器*ngFor,用来显示列表

<h2>My Heroes</h2> 
<ul class="heroes"> 
  <li> 
    <span class="badge">{{hero.id}}</span> {{hero.name}} 
  </li> 
</ul>

现在,把

<li> 

修改成这样:

<li *ngFor="let hero of heroes">

*ngFor 是一个 Angular 的复写器(repeater)指令。 它会为列表中的每项数据复写它的宿主元素。
在这个例子中:
• li就是 *ngFor 的宿主元素
• heroes 就是来自 HeroesComponent 类的列表。
• 当依次遍历这个列表时,hero 会为每个迭代保存当前的英雄对象。

不要忘了 ngFor 前面的星号(*),它是该语法中的关键部分。

2.3.2 事件绑定语法click()

<li *ngFor="let hero of heroes" (click)="onSelect(hero)">

这是 Angular 事件绑定 语法的例子。
click 外面的圆括号会让 Angular 监听这个 li 元素的 click 事件。 当用户点击 li 时,Angular 就会执行表达式 onSelect(hero)。
onSelect() 是 HeroesComponent 上的一个方法,你很快就要写它。 Angular 会把所点击的 li 上的 hero 对象传给它,这个 hero 也就是前面在 *ngFor 表达式中定义的那个。

2.3.3 使用 *ngIf 来根据条件包含或排除一段 HTML

<div *ngIf="selectedHero">
<h2>{{selectedHero.name | uppercase}} Details</h2>
  <div><span>id: </span>{{selectedHero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="selectedHero.name" placeholder="name">
    </label>
  </div>
</div>

当 selectedHero 为 undefined 时,ngIf 从 DOM 中移除了英雄详情。因此也就不用担心 selectedHero 的绑定了。
当用户选择一个英雄时,selectedHero 也就有了值,并且 ngIf 把英雄的详情放回到 DOM 中。

2.3.4 用 class 绑定来切换 CSS 的样式类

Angular 的 CSS 类绑定机制让根据条件添加或移除一个 CSS 类变得很容易。 只要把 [class.some-css-class]=“some-condition” 添加到你要施加样式的元素上就可以了。
在 HeroesComponent 模板中的 li 元素上添加 [class.selected] 绑定,代码如下:

[class.selected]="hero === selectedHero"

如果当前行的英雄和 selectedHero 相同,Angular 就会添加 CSS 类 selected,否则就会移除它。
最终的 li是这样的:

<li *ngFor="let hero of heroes"
  [class.selected]="hero === selectedHero"
  (click)="onSelect(hero)">
  <span class="badge">{{hero.id}}</span> {{hero.name}}
</li>

2.4 主从组件

2.4.1 @Input() 装饰器

@Input() 装饰器,让 hero 属性可以在外部的 HeroesComponent 中绑定。
HeroDetailComponent 模板中绑定了组件中的 hero 属性,它的类型是 Hero。
打开 HeroDetailComponent 类文件,并导入 Hero 符号。

import { Hero } from '../hero';

hero 属性必须是一个带有 @Input() 装饰器的输入属性,因为外部的 HeroesComponent 组件将会绑定到它。就像这样:

<app-hero-detail [hero]="selectedHero"></app-hero-detail> 

修改 @angular/core 的导入语句,导入 Input 符号。

import { Component, OnInit, Input } from '@angular/core';

添加一个带有 @Input() 装饰器的 hero 属性。

@Input() hero: Hero;

这就是你要对 HeroDetailComponent 类做的唯一一项修改。 没有其它属性,也没有展示逻辑。这个组件所做的只是通过 hero 属性接收一个英雄对象,并显示它。

2.4.2 属性数据绑定语法,单向数据绑定

把 HeroesComponent.selectedHero 绑定到该元素的 hero 属性,就像这样:

<app-hero-detail [hero]="selectedHero"></app-hero-detail> 

[hero]=“selectedHero” 是 Angular 的属性绑定语法。
这是一种单向数据绑定。从 HeroesComponent 的 selectedHero 属性绑定到目标元素的 hero 属性,并映射到了 HeroDetailComponent 的 hero 属性。

2.5 服务

2.5.1 服务Service

Angular不光有组件component,还有服务service。
使用 Angular CLI 创建一个名叫 hero 的服务。

ng generate service hero 

该命令会在 src/app/hero.service.ts 中生成 HeroService 类的骨架。
服务是在多个“互相不知道”的类之间共享信息的好办法。
服务类的定义通常紧跟在 “@Injectable()” 装饰器之后。该装饰器提供的元数据可以让你的服务作为依赖被注入到客户组件中。

2.5.2 依赖注入

依赖注入(DI)是一种重要的应用设计模式。 Angular 有自己的 DI 框架,在设计应用时通常会用到它,以提升它们的开发效率和模块化程度。
依赖,是当类需要执行其功能时,所需要的服务或对象。 DI 是一种编码模式,其中的类会从外部源中请求获取依赖,而不是自己创建它们。
在 Angular 中,DI 框架会在实例化该类时向其提供这个类所声明的依赖项。

2.5.3 @Injectable() 服务

这个新的服务导入了 Angular 的 Injectable 符号,并且给这个服务类添加了 @Injectable() 装饰器。 它把这个类标记为依赖注入系统的参与者之一。HeroService 类将会提供一个可注入的服务,并且它还可以拥有自己的待注入的依赖。
@Injectable() 装饰器会接受该服务的元数据对象,就像 @Component() 对组件类的作用一样。

2.5.4 异步函数签名

HeroService 必须等服务器给出响应, 而 getHeroes() 不能立即返回英雄数据, 浏览器也不会在该服务等待期间停止响应。
HeroService.getHeroes() 必须具有某种形式的异步函数签名。
它可以使用回调函数,可以返回 Promise(承诺),也可以返回 Observable(可观察对象)。
这节课,HeroService.getHeroes() 将会返回 Observable,因为它最终会使用 Angular 的 HttpClient.get 方法来获取英雄数据,而 HttpClient.get() 会返回 Observable。

2.5.5 可观察(Observable)的数据

Observable 是 RxJS 库中的一个关键类。
在稍后的 HTTP 教程中,你就会知道 Angular HttpClient 的方法会返回 RxJS 的 Observable。
of(HEROES) 会返回一个 Observable<Hero[]>,它会发出单个值,这个值就是这些模拟英雄的数组。

2.5.6 Observable.subscribe()

上一个版本把英雄的数组赋值给了该组件的 heroes 属性。 这种赋值是同步的,这里包含的假设是服务器能立即返回英雄数组或者浏览器能在等待服务器响应时冻结界面。
当 HeroService 真的向远端服务器发起请求时,这种方式就行不通了。
新的版本等待 Observable 发出这个英雄数组,这可能立即发生,也可能会在几分钟之后。 然后,subscribe 函数把这个英雄数组传给这个回调函数,该函数把英雄数组赋值给组件的 heroes 属性。
使用这种异步方式,当 HeroService 从远端服务器获取英雄数据时,就可以工作了。

2.5.7 服务中的服务

把 MessageService 注入到了 HeroService 中,而 HeroService 又被注入到了 HeroesComponent 中。

2.6 路由

2.6.1 路由器

Angular 的最佳实践之一就是在一个独立的顶级模块中加载和配置路由器,它专注于路由功能,然后由根模块 AppModule 导入它。
路由定义 会告诉路由器,当用户点击某个链接或者在浏览器地址栏中输入某个 URL 时,要显示哪个视图。
典型的 Angular 路由(Route)有两个属性:

  1. path:一个用于匹配浏览器地址栏中 URL 的字符串。
  2. component:当导航到此路由时,路由器应该创建哪个组件。

如果你希望当 URL 为 localhost:4200/heroes 时,就导航到 HeroesComponent。
路由器会在浏览器的历史日志中记录这个动作,所以前进和后退按钮也能正常工作。

2.6.2 RouterModule.forRoot()

你必须首先初始化路由器,并让它开始监听浏览器中的地址变化。
把 RouterModule 添加到 @NgModule.imports 数组中,并用 routes 来配置它。你只要调用 imports 数组中的 RouterModule.forRoot() 函数就行了。

imports: [ RouterModule.forRoot(routes) ],

这个方法之所以叫 forRoot(),是因为你要在应用的顶级配置这个路由器。 forRoot() 方法会提供路由所需的服务提供商和指令,还会基于浏览器的当前 URL 执行首次导航。

2.6.3 路由出口 (RouterOutlet)

<h1>{{title}}</h1>
<router-outlet></router-outlet>
<app-messages></app-messages>  

router-outlet 会告诉路由器要在哪里显示路由到的视图。

2.6.4 路由链接 (routerLink)

不应该让用户只能把路由的 URL 粘贴到地址栏中。他们还应该能通过点击链接进行导航。
添加一个

<h1>{{title}}</h1>
<nav>
  <a routerLink="/heroes">Heroes</a>
</nav>
<router-outlet></router-outlet>
<app-messages></app-messages> 

routerLink 属性的值为 “/heroes”,路由器会用它来匹配出指向 HeroesComponent 的路由。 routerLink 是 RouterLink 指令的选择器,它会把用户的点击转换为路由器的导航操作。 它是 RouterModule 中公开的另一个指令。

发布了42 篇原创文章 · 获赞 15 · 访问量 9794

猜你喜欢

转载自blog.csdn.net/weixin_40326608/article/details/100766266