此刻,HeroesComponent显示heroes列表和所选heroes的详细信息。

随着应用程序的增长保持一个组件中的所有功能将不可维护。您需要将大型组件分成更小的子组件,每个组件都专注于特定的任务或工作流程。

在此页面中,您将通过将heroes详细信息移动到单独的可重复使用的位置来朝此方向迈出第一步HeroDetailsComponent

HeroesComponent会目前唯一的heroes名单。该HeroDetailsComponent会提出一个选择heroes的细节。

9.X-使HeroDetailComponent

使用Angular CLI生成一个名为的新组件hero-detail(组件一般在app目录下生产)

ng generate component hero-detail

该命令脚手架HeroDetailComponent文件并声明组件AppModule

每次创建组件,都会声明到app.module.ts

9.1-编写模板

HeroesComponent模板底部剪下heroes细节的HTML ,并将其粘贴到模板中生成的样板上HeroDetailComponent

粘贴的HTML指的是一个selectedHero。新的HeroDetailComponent可以呈现任何heroes,而不仅仅是一个选定的heroes。因此,在模板中的任何地方都将“selectedHero”替换为“hero”。

完成后,HeroDetailComponent模板应该如下所示:

herodetail.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>

9.2-添加heroes属性@Input()

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

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

src / app / hero-detail / hero-detail.component.ts(导入heroes)

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

hero属性 必须是一个Input属性,用装饰器注释,因为外部像这样绑定到它@Input() HeroesComponent

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

修改@angular/core进口声明以包含Input符号。

src / app / hero-detail / hero-detail.component.ts(导入输入)

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

添加一个hero属性,在装饰器之前。@Input()

@Input() hero: Hero;

这是你应该对HeroDetailComponent班上唯一的改变。没有更多的属性。没有表示逻辑。该组件仅通过其hero属性接收heroes对象并显示它。

9.3-显示HeroDetailComponent

HeroesComponent仍然是主/细节视图。

它用于在切割模板的该部分之前自行显示heroes详细信息。现在它将委托给HeroDetailComponent

这两个组件将具有父母/子女关系。父母HeroesComponentHeroDetailComponent 通过发送一个新的heroes来控制孩子,以便在用户从列表中选择heroes时显示。

你不会改变HeroesComponent 班级,但你会改变它的模板

更新HeroesComponent模板

HeroDetailComponent选择是'app-hero-detail'<app-hero-detail>HeroesComponent模板底部附近添加一个元素,其中heroes细节视图曾经是。

像这样绑定HeroesComponent.selectedHero元素的hero属性。

heroes.component.html(HeroDetail绑定)

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

[hero]="selectedHero"是一个Angular 属性绑定

这是一个单向的数据从绑定selectedHero的属性HeroesComponenthero目标元素,它映射到的财产hero的性质HeroDetailComponent

现在,当用户点击列表中的heroes时,selectedHero就会发生变化。当selectedHero更改时,属性绑定更新hero 并HeroDetailComponent显示新的heroes。

修改后的HeroesComponent模板应该如下所示:

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

浏览器刷新并且应用程序重新开始工作,就像以前一样。

什么改变?

以前一样,只要用户点击heroes名字,heroes详情就会出现在heroes列表下方。现在HeroDetailComponent是呈现这些细节,而不是HeroesComponent

将原件重构HeroesComponent为两个组件,现在和未来都会带来好处:

  1. HeroesComponent通过减少责任来简化它。

  2. 你可以演变HeroDetailComponent成一个丰富的heroes编辑器,而无需触摸父母HeroesComponent

  3. 你可以在HeroesComponent不触及heroes细节视图的情况下进化。

  4. 您可以重新使用HeroDetailComponent未来组件的模板。

src/app/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>
src/app/herodetail.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { Hero } from '../hero'; @Component({
selector: 'app-hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls: ['./hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {
@Input() hero: Hero; constructor() { } ngOnInit() {
} }
src/app/heroes/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>

如果需要看出区别,源码如下:

Angualr2.x-列表

 --------------------------------------------------------------------------
//heroes.component.ts import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HEROES } from '../mock-heroes'; @Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit { heroes = HEROES; selectedHero: Hero; constructor() { } ngOnInit() {
} onSelect(hero: Hero): void {
this.selectedHero = hero;
}
} --------------------------------------------------------------------------
//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> <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> --------------------------------------------------------------------------
//heroes.component.css .selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 15em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0;
height: 1.6em;
border-radius: 4px;
}
.heroes li.selected:hover {
background-color: #BBD8DC !important;
color: white;
}
.heroes li:hover {
color: #607D8B;
background-color: #DDD;
left: .1em;
}
.heroes .text {
position: relative;
top: -3px;
}
.heroes .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0 0 4px;
}

Angular2.x-子组件

 <--!
  hero-detail.component.ts
-->
import { Component, OnInit, Input } from '@angular/core';
import { Hero } from '../hero'; @Component({
selector: 'app-hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls: ['./hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {
@Input() hero: Hero; constructor() { } ngOnInit() {
} }
----------------------------------------------------------------------------------
<--!
  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>
-----------------------------------------------------------------------------------
<--!
  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>

简述的话,也就是:

1. 在app下生成

ng generate component hero-detail

2.heroes.component.html复制到hero-detail.component.html(selectedHero内容全部修改为hero)

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

3.在hero-detail.component.ts(导入heroes)

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

4.在hero-detail.component.ts(导入输入)

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

5.添加一个hero属性,在装饰器之前。@Input()

@Input() hero: Hero;

6.显示heroes.component.html

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

  

  

最新文章

  1. MonkeyRunner测试一MonkeyRunner的使用
  2. Timing path
  3. 【转】cvs2svn 把CVS档案库转换为SVN档案库
  4. SecureCRT的SFTP在Windows与Linux之间传输文件
  5. for语句中声明变量
  6. Android下的Linux指令集
  7. Java下拼接执行动态SQL语句(转)
  8. 三.redis 排序
  9. SpringMvc项目中使用GoogleKaptcha 生成验证码
  10. 「POJ2505」A multiplication game [博弈论]
  11. 常见常用的CSS
  12. R语法学习 第十二篇:因子
  13. centos7搭建GitLab
  14. LeetCode 145. Binary Tree Postorder Traversal 二叉树的后序遍历 C++
  15. 基于Gradle的spring boot 项目构建
  16. nginx unit的初探
  17. ASP.NET Identity 一 (转载)
  18. 在centos7虚拟机上挂载镜像,并设置yum源(包括遇到的问题)
  19. linux:rsync + inotifywait 实现【准实时】同步
  20. 插件:★★★ !!!图片懒加载 lazyload.js 、 jquery.scrollLoading.js

热门文章

  1. 二叉排序树BST
  2. STL || Gym 101653U Top 25
  3. 尺取法 || POJ 2739 Sum of Consecutive Prime Numbers
  4. Spring框架针对dao层的jdbcTemplate操作之jdbc数据库连接原始操作方法 所需安装包下载
  5. c++的if语句中的110为什么不等于110?
  6. Java 一些常见问题(持续更新)
  7. Django框架基础知识03-模板变量及模板过滤器
  8. ASP.NET Core on K8S学习初探(1)K8S单节点环境搭建
  9. MyBatis 3 学习
  10. 大数据学习——redis安装