W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
此刻,?HeroesComponent
?同時(shí)顯示了英雄列表和所選英雄的詳情。
把所有特性都放在同一個(gè)組件中,將會(huì)使應(yīng)用“長(zhǎng)大”后變得不可維護(hù)。你要把大型組件拆分成小一點(diǎn)的子組件,每個(gè)子組件都要集中精力處理某個(gè)特定的任務(wù)或工作流。
本頁面中,你將邁出第一步 —— 把英雄詳情移入一個(gè)獨(dú)立的、可復(fù)用的 ?HeroDetailComponent
?。
?HeroesComponent
?將僅僅用來表示英雄列表。?HeroDetailComponent
?將用來表示所選英雄的詳情。
要查看本頁所講的范例程序,參閱現(xiàn)場(chǎng)演練 / 下載范例。
使用 Angular CLI 生成一個(gè)名叫 ?hero-detail
? 的新組件。
ng generate component hero-detail
這個(gè)命令會(huì)做這些事:
src/app/hero-detail
?。在這個(gè)目錄中會(huì)生成四個(gè)文件:
HeroDetailComponent
?的 TypeScript 文件。HeroDetailComponent
?類的測(cè)試文件。該命令還會(huì)把 ?HeroDetailComponent
?添加到 ?src/app/app.module.ts
? 文件中 ?@NgModule
? 的 ?declarations
?列表中。
從 ?HeroesComponent
?模板的底部把表示英雄詳情的 HTML 代碼剪切粘貼到所生成的 ?HeroDetailComponent
?模板中。
所粘貼的 HTML 引用了 ?selectedHero
?。新的 ?HeroDetailComponent
?可以展示任意英雄,而不僅僅所選的。因此還要把模板中的所有 ?selectedHero
?替換為 ?hero
?。
完工之后,?HeroDetailComponent
?的模板應(yīng)該是這樣的:
<div *ngIf="hero">
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label for="hero-name">Hero name: </label>
<input id="hero-name" [(ngModel)]="hero.name" placeholder="name">
</div>
</div>
?HeroDetailComponent
?模板中綁定了組件中的 ?hero
?屬性,它的類型是 ?Hero
?。
打開 ?HeroDetailComponent
?類文件,并導(dǎo)入 ?Hero
?符號(hào)。
import { Hero } from '../hero';
?hero
?屬性必須是一個(gè)帶有 ?@Input()
? 裝飾器的輸入屬性,因?yàn)橥獠康?nbsp;?HeroesComponent
?組件將會(huì)綁定到它。就像這樣:
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
修改 ?@angular/core
? 的導(dǎo)入語句,導(dǎo)入 ?Input
?符號(hào)。
import { Component, OnInit, Input } from '@angular/core';
添加一個(gè)帶有 ?@Input()
? 裝飾器的 ?hero
?屬性。
@Input() hero?: Hero;
這就是你要對(duì) ?HeroDetailComponent
?類做的唯一一項(xiàng)修改。沒有其它屬性,也沒有展示邏輯。這個(gè)組件所做的只是通過 ?hero
?屬性接收一個(gè)英雄對(duì)象,并顯示它。
?HeroesComponent
?會(huì)自行顯示英雄的詳情,但后面我們要移除這部分。本節(jié)會(huì)指導(dǎo)你把這部分邏輯委派給 ?HeroDetailComponent
?。
這兩個(gè)組件將會(huì)具有父子關(guān)系。當(dāng)用戶從列表中選擇了某個(gè)英雄時(shí),父組件 ?HeroesComponent
?將通過把要顯示的新英雄發(fā)送給子組件 ?HeroDetailComponent
?,來控制子組件。
你不用修改 ?HeroesComponent
? 類,但是要修改它的模板。
?HeroDetailComponent
?的選擇器是 ?'app-hero-detail'
?。把 ?<app-hero-detail>
? 添加到 ?HeroesComponent
?模板的底部,以便把英雄詳情的視圖顯示到那里。
把 ?HeroesComponent.selectedHero
? 綁定到該元素的 ?hero
?屬性,就像這樣。
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
?[hero]="selectedHero"
? 是 Angular 的屬性綁定語法。
這是一種單向數(shù)據(jù)綁定。從 ?HeroesComponent
?的 ?selectedHero
?屬性綁定到目標(biāo)元素的 ?hero
?屬性,并映射到了 ?HeroDetailComponent
?的 ?hero
?屬性。
現(xiàn)在,當(dāng)用戶在列表中點(diǎn)擊某個(gè)英雄時(shí),?selectedHero
?就改變了。當(dāng) ?selectedHero
?改變時(shí),屬性綁定會(huì)修改 ?HeroDetailComponent
?的 ?hero
?屬性,?HeroDetailComponent
?就會(huì)顯示這個(gè)新的英雄。
修改后的 ?HeroesComponent
?的模板是這樣的:
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes">
<button [class.selected]="hero === selectedHero" type="button" (click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span>
<span class="name">{{hero.name}}</span>
</button>
</li>
</ul>
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
瀏覽器刷新,應(yīng)用又像以前一樣開始工作了。
像以前一樣,一旦用戶點(diǎn)擊了一個(gè)英雄的名字,該英雄的詳情就顯示在了英雄列表下方?,F(xiàn)在,?HeroDetailComponent
?負(fù)責(zé)顯示那些詳情,而不再是 ?HeroesComponent
?。
把原來的 ?HeroesComponent
?重構(gòu)成兩個(gè)組件帶來了一些優(yōu)點(diǎn),無論是現(xiàn)在還是未來:
HeroesComponent
?的職責(zé)縮小了該組件。HeroDetailComponent
?改進(jìn)成一個(gè)功能豐富的英雄編輯器,而不用改動(dòng)父組件 ?HeroesComponent
?。HeroesComponent
?,而不用改動(dòng)英雄詳情視圖。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(): void {
}
}
<div *ngIf="hero">
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label for="hero-name">Hero name: </label>
<input id="hero-name" [(ngModel)]="hero.name" placeholder="name">
</div>
</div>
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes">
<button [class.selected]="hero === selectedHero" type="button" (click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span>
<span class="name">{{hero.name}}</span>
</button>
</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 { }
HeroDetailComponent
?組件。
HeroesComponent
?可以控制子組件 ?HeroDetailComponent
?。
@Input
? 裝飾器來讓 ?hero
?屬性可以在外部的 ?HeroesComponent
?中綁定。Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: