W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
此刻,HeroesComponent 同時顯示了英雄列表和所選英雄的詳情。
把所有特性都放在同一個組件中,將會使應用“長大”后變得不可維護。 你要把大型組件拆分成小一點的子組件,每個子組件都要集中精力處理某個特定的任務或工作流。
本頁面中,你將邁出第一步 —— 把英雄詳情移入一個獨立的、可復用的 HeroDetailComponent。
HeroesComponent 將僅僅用來表示英雄列表。 HeroDetailComponent 將用來表示所選英雄的詳情。
使用 Angular CLI 生成一個名叫 hero-detail 的新組件。
ng generate component hero-detail
這個命令會做這些事:
在這個目錄中會生成四個文件:
該命令還會把 HeroDetailComponent 添加到 "src/app/app.module.ts" 文件中 @NgModule
的 declarations
列表中。
從 HeroesComponent 模板的底部把表示英雄詳情的 HTML 代碼剪切粘貼到所生成的 HeroDetailComponent 模板中。
所粘貼的 HTML 引用了 selectedHero
。 新的 HeroDetailComponent 可以展示任意英雄,而不僅僅所選的。因此還要把模板中的所有 selectedHero
替換為 hero
。
完工之后,HeroDetailComponent
的模板應該是這樣的:
Path:"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>
HeroDetailComponent 模板中綁定了組件中的 hero
屬性,它的類型是 Hero
。
打開 HeroDetailComponent 類文件,并導入 Hero
符號。
Path:"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
符號。
Path:"src/app/hero-detail/hero-detail.component.ts (import Input)"
import { Component, OnInit, Input } from '@angular/core';
添加一個帶有 @Input()
裝飾器的 hero
屬性。
Path:"src/app/hero-detail/hero-detail.component.ts"
@Input() hero: Hero;
這就是你要對 HeroDetailComponent 類做的唯一一項修改。 沒有其它屬性,也沒有展示邏輯。這個組件所做的只是通過 hero
屬性接收一個英雄對象,并顯示它。
HeroesComponent 仍然是主從視圖。
在你從模板中剪切走代碼之前,它自己負責顯示英雄的詳情?,F(xiàn)在它要把這個職責委托給 HeroDetailComponent 了。
這兩個組件將會具有父子關系。 當用戶從列表中選擇了某個英雄時,父組件 HeroesComponent 將通過把要顯示的新英雄發(fā)送給子組件 HeroDetailComponent,來控制子組件。
你不用修改 HeroesComponent 類,但是要修改它的模板。
HeroDetailComponent 的選擇器是 'app-hero-detail'
。 把 <app-hero-detail>
添加到 HeroesComponent 模板的底部,以便把英雄詳情的視圖顯示到那里。
把 HeroesComponent.selectedHero 綁定到該元素的 hero
屬性,就像這樣:
Path:"heroes.component.html (HeroDetail binding)"
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
[hero]="selectedHero"
是 Angular 的屬性綁定語法。
這是一種單向數(shù)據(jù)綁定。從 HeroesComponent 的 selectedHero 屬性綁定到目標元素的 hero
屬性,并映射到了 HeroDetailComponent 的 hero
屬性。
現(xiàn)在,當用戶在列表中點擊某個英雄時,selectedHero
就改變了。 當 selectedHero
改變時,屬性綁定會修改 HeroDetailComponent 的 hero
屬性,HeroDetailComponent 就會顯示這個新的英雄。
修改后的 HeroesComponent 的模板是這樣的:
Path:"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>
瀏覽器刷新,應用又像以前一樣開始工作了。
產生的變化:
像以前一樣,一旦用戶點擊了一個英雄的名字,該英雄的詳情就顯示在了英雄列表下方。 現(xiàn)在,HeroDetailComponent 負責顯示那些詳情,而不再是 HeroesComponent。
把原來的 HeroesComponent 重構成兩個組件帶來了一些優(yōu)點,無論是現(xiàn)在還是未來:
你通過縮減 HeroesComponent 的職責簡化了該組件。
你可以把 HeroDetailComponent 改進成一個功能豐富的英雄編輯器,而不用改動父組件 HeroesComponent。
你可以改進 HeroesComponent,而不用改動英雄詳情視圖。
將來你可以在其它組件的模板中重復使用 HeroDetailComponent。
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() {
}
}
<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>
<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>
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HeroesComponent } from './heroes/heroes.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
@NgModule({
declarations: [
AppComponent,
HeroesComponent,
HeroDetailComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: