Angular 主从组件

此刻,HeroesComponent同时显示了英雄列表和所选英雄的详情。

把所有特性都放在同一个组件中,将会使应用“长大”后变得不可维护。 你要把大型组件拆分成小一点的子组件,每个子组件都要集中精力处理某个特定的任务或工作流。

本页面中,你将迈出第一步 —— 把英雄详情移入一个独立的、可复用的HeroDetailComponent。

HeroesComponent将仅仅用来表示英雄列表。HeroDetailComponent将用来表示所选英雄的详情。

你可以访问下面的链接https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail从 GitHub 上查看我们提供源代码。

制作HeroDetailComponent

使用 Angular CLI 生成一个名叫hero-detail的新组件。

ng generate component hero-detail

这个命令会做这些事:

创建一个目录src/app/hero-detail.

在这个目录中会生成四个文件:

作为组件样式的 CSS 文件。

作为组件模板的 HTML 文件。

存放组件类HeroDetailComponent的 TypeScript 文件。

HeroDetailComponent类的测试文件。

该命令还会把HeroDetailComponent添加到src/app/app.module.ts文件中@NgModuledeclarations列表中。

编写模板

从HeroesComponent模板的底部把表示英雄详情的 HTML 代码剪切粘贴到所生成的HeroDetailComponent模板中。

所粘贴的 HTML 引用了selectedHero。 新的HeroDetailComponent可以展示任意英雄,而不仅仅所选的。因此还要把模板中的所有selectedHero替换为hero。

完工之后,HeroDetailComponent的模板应该是这样的:

src/app/hero-detail/hero-detail.component.html

<div *ngIf="hero">


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

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

  <div>

    <label>name:

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

    </label>

  </div>


</div>

添加@Input()hero 属性

HeroDetailComponent模板中绑定了组件中的hero属性,它的类型是Hero。

打开HeroDetailComponent类文件,并导入Hero符号。

src/app/hero-detail/hero-detail.component.ts (import Hero)

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

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

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

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

src/app/hero-detail/hero-detail.component.ts (import Input)

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

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

@Input() hero: Hero;

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

显示HeroDetailComponent

HeroesComponent仍然是主从视图。

在你从模板中剪切走代码之前,它自己负责显示英雄的详情。现在它要把这个职责委托给HeroDetailComponent了。

这两个组件将会具有父子关系。 当用户从列表中选择了某个英雄时,父组件HeroesComponent将通过把要显示的新英雄发送给子组件HeroDetailComponent,来控制子组件。

你不用修改HeroesComponent,但是要修改它的模板

修改HeroesComponent的模板

HeroDetailComponent的选择器是'app-hero-detail'。 把<app-hero-detail>添加到HeroesComponent模板的底部,以便把英雄详情的视图显示到那里。

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

heroes.component.html (HeroDetail binding)

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

[hero]="selectedHero"是 Angular 的属性绑定语法。

这是一种单向数据绑定。从HeroesComponent的selectedHero属性绑定到目标元素的hero属性,并映射到了HeroDetailComponent的hero属性。

现在,当用户在列表中点击某个英雄时,selectedHero就改变了。 当selectedHero改变时,属性绑定会修改HeroDetailComponent的hero属性,HeroDetailComponent就会显示这个新的英雄。

修改后的HeroesComponent的模板是这样的:

heroes.component.html

<h2>My Heroes</h2>


<ul class="heroes">

  <li *ngFor="let hero of heroes"

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

    (click)="onSelect(hero)">

    <span class="badge">{{hero.id}}</span> {{hero.name}}

  </li>

</ul>


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

浏览器刷新,应用又像以前一样开始工作了。

修改了什么?

以前一样,一旦用户点击了一个英雄的名字,该英雄的详情就显示在了英雄列表下方。 现在,HeroDetailComponent负责显示那些详情,而不再是HeroesComponent。

把原来的HeroesComponent重构成两个组件带来了一些优点,无论是现在还是未来:

你通过缩减HeroesComponent的职责简化了该组件。

你可以把HeroDetailComponent改进成一个功能丰富的英雄编辑器,而不用改动父组件HeroesComponent。

你可以改进HeroesComponent,而不用改动英雄详情视图。

将来你可以在其它组件的模板中重复使用HeroDetailComponent。

查看最终代码

你的应用应该变成了这样在线例子/下载范例。本页所提及的代码文件如下:

如果你想直接在 stackblitz 运行本页中的例子,请单击链接:https://stackblitz.com/github/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail

本页中所提及的代码如下:https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail

对应的文件列表和代码链接如下:

文件名源代码

src/app/hero-detail/hero-detail.component.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail/blob/master/src/app/hero-detail/hero-detail.component.ts

src/app/hero-detail/hero-detail.component.htmlhttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail/blob/master/src/app/hero-detail/hero-detail.component.html

src/app/heroes/heroes.component.htmlhttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail/blob/master/src/app/heroes/heroes.component.html

src/app/app.module.tshttps://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-master-detail/blob/master/src/app/app.module.ts

小结

你创建了一个独立的、可复用的HeroDetailComponent组件。

你用属性绑定语法来让父组件HeroesComponent可以控制子组件HeroDetailComponent。

你用@Input装饰器来让hero属性可以在外部的HeroesComponent中绑定。

https://www.cwiki.us/pages/viewpage.action?pageId=47841998

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

推荐阅读更多精彩内容

  • 应用程序现在有了基本的标题。 接下来你要创建一个新的组件来显示英雄信息并且把这个组件放到应用程序的外壳里去。 创建...
    HoneyMoose阅读 1,138评论 0 0
  • 在本页面,你将扩展《英雄指南》应用,让它显示一个英雄列表, 并允许用户选择一个英雄,查看该英雄的详细信息。 创建模...
    HoneyMoose阅读 609评论 0 0
  • Angular 2架构总览 - 简书http://www.jianshu.com/p/aeb11061b82c A...
    葡萄喃喃呓语阅读 1,485评论 2 13
  • 根据名字搜索 https://angular.io/tutorial/toh-pt6#search-by-name...
    哪种生活可以永远很轻松阅读 273评论 0 1
  • 版本:4.0.0+2 有一些英雄指南应用的新需求: 添加一个仪表盘 视图。 添加在英雄 视图和 仪表盘 视图之间导...
    soojade阅读 1,296评论 0 0