应用程序现在有了基本的标题。 接下来你要创建一个新的组件来显示英雄信息并且把这个组件放到应用程序的外壳里去。
创建英雄组件
使用 Angular CLI 创建一个名为heroes的新组件。
ng generate component heroes
CLI 创建了一个新的文件夹,src/app/heroes/,并生成了HeroesComponent的 4 个文件。
HeroesComponent的类文件如下:
heroes.component.ts
import{ Component, OnInit } from '@angular/core';
@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export classHeroesComponent implementsOnInit {
constructor() { }
ngOnInit() {
}
}
你要从 Angular 核心库中导入
Component
符号,并为组件类加上@
Component
注解。
@Component是一个修饰器函数,这个函数为组件指定了 Angular 元数据。
CLI 自动生成了三个元数据属性:
selector — 组件的 CSS 元素选择器。
templateUrl — 组件模板文件的位置。
styleUrls — 组件私有 CSS 样式表文件的位置。
CSS 元素选择器app-heroes用来在父组件的模板中匹配 HTML 元素的名称,以识别出该组件。
ngOnInit是一个生命周期钩子(lifecycle hook),Angular 在创建完组件后很快就会调用ngOnInit。这里是放置初始化逻辑的好地方。
始终要export这个组件类,以便于在其它地方(比如AppModule)导入它。
添加一个hero属性
往HeroesComponent中添加一个hero属性,用来表示一个名叫 “Windstorm” 的英雄。
hero = 'Windstorm';
显示英雄
打开模板文件heroes.component.html。删除 Angular CLI 自动生成的默认内容,改为到hero属性的数据绑定。
heroes.component.html
{{hero}}
显示HeroesComponent视图
要显示HeroesComponent你必须把它加到壳组件AppComponent的模板中。
别忘了,app-heroes就是HeroesComponent的元素选择器(element selector)。 所以,只要把
app.component.html
{{title}}
如果 CLI 的ng serve命令仍在运行,浏览器就会自动刷新,并且同时显示出应用的标题和英雄的名字。
创建一个 Hero 类
真实的英雄当然不仅仅只有一个名字。
在src/app文件夹中为Hero类创建一个文件,并添加id和name属性。
src/app/hero.ts
export classHero {
id: number;
name: string;
}
回到HeroesComponent类,并且导入这个Hero类。
把组件的hero属性的类型重构为Hero。 然后以1为id、以 “Windstorm” 为名字初始化它。
修改后的HeroesComponent类应该是这样的:
src/app/heroes/heroes.component.ts
import{Component, OnInit} from '@angular/core';
import{Hero} from '../hero';
@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export classHeroesComponent implementsOnInit {
hero: Hero = {
id: 1,
name: 'Windstorm'
};
constructor() {
}
ngOnInit() {
}
}
页面显示变得不正常了,因为你刚刚把hero从字符串改成了对象。
显示hero对象
修改模板中的绑定,以显示英雄的名字,并在详情中显示id和name,就像这样:
heroes.component.html (HeroesComponent 的模板)
{{hero.name}} Details
浏览器自动刷新,并显示这位英雄的信息。
使用UppercasePipe进行格式化
把hero.name的绑定修改成这样:
{{hero.name | uppercase}} Details
对浏览器进行刷新。现在,你会发现英雄的名字显示成了大写字母。
位于管道操作符( | )的右边的单词uppercase表示的是一个插值绑定,用于调用内置的UppercasePipe。
管道(Pipes)是格式化字符串、金额、日期和其它显示数据的好办法。 Angular 发布了一些内置管道,当然你还可以创建自己的管道。
编辑英雄
用户应该能在一个文本输入框(textbox)中编辑英雄的名字。
当用户输入时,这个输入框应该能同时显示和修改英雄的name属性。 也就是说,数据流从组件类流出到屏幕,并且从屏幕流回到组件类。
要想让这种数据流动自动化,就要在表单元素和组件的hero.name属性之间建立双向数据绑定。
双向绑定
把HeroesComponent 模板中的英雄详情区重构成这样:
src/app/heroes/heroes.component.html (HeroesComponent 模板)
[(ngModel)]是 Angular 的双向数据绑定句法。
这里把hero.name属性绑定到了 HTML 的 textbox 元素上,以便数据流可以双向流动:从hero.name属性流动到 textbox,并且从 textbox 流回到hero.name。
缺少FormsModule
注意,当你加上[(ngModel)] 之后这个应用无法工作了。
打开浏览器的开发工具,就会在控制台中看到如下信息:
Uncaught Error: Template parse errors:
Can't bind to 'ngModel' since it isn't a known property of 'input'.
虽然ngModel是一个有效的 Angular 指令,不过它在默认情况下是不可用的。
它属于一个可选模块FormsModule,你必须自行添加此模块才能使用该指令。
AppModule
Angular 需要知道如何把应用程序的各个部分组合到一起,以及该应用需要哪些其它文件和库。 这些信息被称为元数据(metadata)。
最重要的@NgModule装饰器位于顶级类AppModule上。
Angular CLI 在创建项目的时候就在src/app/app.module.ts中生成了一个AppModule类。 这里也就是你要添加FormsModule的地方。
导入FormsModule
打开AppModule(app.module.ts) 并从@angular/forms库中导入FormsModule符号。
app.module.ts (FormsModule 符号导入)
import{FormsModule} from '@angular/forms';
然后把FormsModule添加到@NgModule元数据的imports数组中,这里是该应用所需外部模块的列表。
app.module.ts(@NgModule 导入)
imports: [
BrowserModule,
FormsModule
],
刷新浏览器,应用又能正常工作了。你可以编辑英雄的名字,并且会看到这个改动立刻体现在这个输入框上方的
中。
声明HeroesComponent
每个组件都必须声明在(且只能声明在)一个NgModule中。
你没有声明过HeroesComponent,可为什么应用却正常工作呢?
这是因为 Angular CLI 在生成HeroesComponent组件的时候就自动把它加到了AppModule中。
打开src/app/app.module.ts你可以在顶部找到HeroesComponent已经被导入过了。
src/app/app.module.ts
import{HeroesComponent} from './heroes/heroes.component';
HeroesComponent也已经声明在了@NgModule.declarations数组中。
declarations: [
AppComponent,
HeroesComponent
],
注意:AppModule声明了应用中的所有组件,AppComponent和HeroesComponent。
最终代码预览
应用跑起来应该是这样的:在线例子/下载范例。
如果你想直接在 stackblitz 运行本页中的例子,请单击链接:https://stackblitz.com/github/cwiki-us-angular/cwiki-us-angular-tour-of-hero-editor
本页中所提及的代码如下:https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-editor
对应的文件列表和代码链接如下:
文件名源代码
src/app/heroes/heroes.component.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-editor/blob/master/src/app/heroes/heroes.component.ts
src/app/heroes/heroes.component.htmlhttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-editor/blob/master/src/app/heroes/heroes.component.html
src/app/app.module.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-editor/blob/master/src/app/app.module.ts
src/app/app.component.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-editor/blob/master/src/app/app.component.ts
src/app/app.component.htmlhttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-editor/blob/master/src/app/app.component.html
src/app/hero.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-hero-editor/blob/master/src/app/hero.ts
小结
你使用 CLI 创建了第二个组件HeroesComponent。
你把HeroesComponent添加到了壳组件AppComponent中,以便显示它。
你使用UppercasePipe来格式化英雄的名字。
你用ngModel指令实现了双向数据绑定。
你知道了AppModule。
你把FormsModule导入了AppModule,以便 Angular 能识别并应用ngModel指令。
你知道了把组件声明到AppModule是很重要的,并认识到 CLI 会自动帮你声明它。
https://www.cwiki.us/display/AngularZH/The+Hero+Editor