Angular2.x-主/细节组件

此刻,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-列表

  1 --------------------------------------------------------------------------
  2 //heroes.component.ts
  3 
  4 import { Component, OnInit } from '@angular/core';
  5 import { Hero } from '../hero';
  6 import { HEROES } from '../mock-heroes';
  7  
  8 @Component({
  9   selector: 'app-heroes',
 10   templateUrl: './heroes.component.html',
 11   styleUrls: ['./heroes.component.css']
 12 })
 13 export class HeroesComponent implements OnInit {
 14  
 15   heroes = HEROES;
 16  
 17   selectedHero: Hero;
 18  
 19  
 20   constructor() { }
 21  
 22   ngOnInit() {
 23   }
 24  
 25   onSelect(hero: Hero): void {
 26     this.selectedHero = hero;
 27   }
 28 }
 29 
 30 --------------------------------------------------------------------------
 31 //heroes.component.html
 32 
 33 <h2>My Heroes</h2>
 34 <ul class="heroes">
 35   <li *ngFor="let hero of heroes"
 36     [class.selected]="hero === selectedHero"
 37     (click)="onSelect(hero)">
 38     <span class="badge">{{hero.id}}</span> {{hero.name}}
 39   </li>
 40 </ul>
 41  
 42 <div *ngIf="selectedHero">
 43  
 44   <h2>{{ selectedHero.name | uppercase }} Details</h2>
 45   <div><span>id: </span>{{selectedHero.id}}</div>
 46   <div>
 47     <label>name:
 48       <input [(ngModel)]="selectedHero.name" placeholder="name">
 49     </label>
 50   </div>
 51  
 52 </div>
 53 
 54 
 55 --------------------------------------------------------------------------
 56 //heroes.component.css
 57 
 58 .selected {
 59   background-color: #CFD8DC !important;
 60   color: white;
 61 }
 62 .heroes {
 63   margin: 0 0 2em 0;
 64   list-style-type: none;
 65   padding: 0;
 66   width: 15em;
 67 }
 68 .heroes li {
 69   cursor: pointer;
 70   position: relative;
 71   left: 0;
 72   background-color: #EEE;
 73   margin: .5em;
 74   padding: .3em 0;
 75   height: 1.6em;
 76   border-radius: 4px;
 77 }
 78 .heroes li.selected:hover {
 79   background-color: #BBD8DC !important;
 80   color: white;
 81 }
 82 .heroes li:hover {
 83   color: #607D8B;
 84   background-color: #DDD;
 85   left: .1em;
 86 }
 87 .heroes .text {
 88   position: relative;
 89   top: -3px;
 90 }
 91 .heroes .badge {
 92   display: inline-block;
 93   font-size: small;
 94   color: white;
 95   padding: 0.8em 0.7em 0 0.7em;
 96   background-color: #607D8B;
 97   line-height: 1em;
 98   position: relative;
 99   left: -1px;
100   top: -4px;
101   height: 1.8em;
102   margin-right: .8em;
103   border-radius: 4px 0 0 4px;
104 }

Angular2.x-子组件 

 1 <--!
 2   hero-detail.component.ts
 3 -->
 4 import { Component, OnInit, Input } from '@angular/core';
 5 import { Hero } from '../hero';
 6  
 7 @Component({
 8   selector: 'app-hero-detail',
 9   templateUrl: './hero-detail.component.html',
10   styleUrls: ['./hero-detail.component.css']
11 })
12 export class HeroDetailComponent implements OnInit {
13   @Input() hero: Hero;
14  
15   constructor() { }
16  
17   ngOnInit() {
18   }
19  
20 }
21 ----------------------------------------------------------------------------------
22 <--!
23   hero-detail.component.html
24 -->
25 <div *ngIf="hero">
26 
27   <h2>{{ hero.name | uppercase }} Details</h2>
28   <div><span>id: </span>{{hero.id}}</div>
29   <div>
30     <label>name:
31       <input [(ngModel)]="hero.name" placeholder="name"/>
32     </label>
33   </div>
34 
35 </div>
36 -----------------------------------------------------------------------------------
37 <--!
38   heroes.component.html
39 -->
40 <h2>My Heroes</h2>
41 
42 <ul class="heroes">
43   <li *ngFor="let hero of heroes"
44     [class.selected]="hero === selectedHero"
45     (click)="onSelect(hero)">
46     <span class="badge">{{hero.id}}</span> {{hero.name}}
47   </li>
48 </ul>
49 
50 <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>

  

 

  

posted @ 2018-03-08 10:55  Sunsin  阅读(207)  评论(0编辑  收藏  举报