Angular 英雄编辑器

应用程序现在有了基本的标题。 接下来你要创建一个新的组件来显示英雄信息并且把这个组件放到应用程序的外壳里去。

创建英雄组件

使用 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-heroes>元素添加到AppComponent的模板文件(app.component.html)中就可以了,就放在标题下方。

app.component.html

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

<app-heroes></app-heroes>

如果 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 的模板)

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

<div><span>id: </span>{{hero.id}}</div>

<div><span>name: </span>{{hero.name}}</div>

浏览器自动刷新,并显示这位英雄的信息。

使用UppercasePipe进行格式化

hero.name的绑定修改成这样:

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

对浏览器进行刷新。现在,你会发现英雄的名字显示成了大写字母。

位于管道操作符( | )的右边的单词uppercase表示的是一个插值绑定,用于调用内置的UppercasePipe。

管道(Pipes)是格式化字符串、金额、日期和其它显示数据的好办法。 Angular 发布了一些内置管道,当然你还可以创建自己的管道。

编辑英雄

用户应该能在一个<input>文本输入框(textbox)中编辑英雄的名字。

当用户输入时,这个输入框应该能同时显示修改英雄的name属性。 也就是说,数据流从组件类流出到屏幕,并且从屏幕流回到组件类

要想让这种数据流动自动化,就要在表单元素<input>和组件的hero.name属性之间建立双向数据绑定。

双向绑定

把HeroesComponent 模板中的英雄详情区重构成这样:

src/app/heroes/heroes.component.html (HeroesComponent 模板)

<div>

  <label>name:

    <input [(ngModel)]="hero.name"placeholder="name"/>

  </label>

</div>

[(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

],

刷新浏览器,应用又能正常工作了。你可以编辑英雄的名字,并且会看到这个改动立刻体现在这个输入框上方的<h2>中。

声明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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容