哈囉,各位邦友們!
昨天完成用事件綁定與 @for/@if 搭配 scss 來實現選中狀態時的互動。
今天來試著挑戰透過input編輯英雄名稱,並且在畫面上即時更新。
一、在 Standalone 中加入 FormsModule
// src/app/app.ts
// ...existing code...
import { FormsModule } from '@angular/forms';
// ...existing code...
@Component({
// ...existing code...
imports: [HeroBadge, FormsModule],
// ...existing code...
})
export class App {
// ...existing code...
protected readonly heroes = signal<Hero[]>([
{ id: 11, name: 'Dr Nice', rank: 'B' },
{ id: 12, name: 'Narco', rank: 'A' },
{ id: 13, name: 'Bombasto' },
{ id: 14, name: 'Celeritas', rank: 'S' },
]);
protected readonly selectedHero = signal<Hero | null>(null);
// 新增:同步更新 selectedHero 與 heroes 清單
updateName(name: string) {
const selected = this.selectedHero();
if (!selected) {
return;
}
// 1. 建立更新後的英雄物件
const updatedHero = { ...selected, name };
// 2. 更新英雄列表 (heroes signal)
this.heroes.update(list =>
list.map(hero => (hero.id === updatedHero.id ? updatedHero : hero))
);
// 3. 更新當前選取的英雄 (selectedHero signal)
this.selectedHero.set(updatedHero);
}
}
二、用 ngModel 編輯選中英雄名稱並驗證
<!-- src/app/app.html -->
<!-- ...existing code... -->
<section>
<!-- ...existing code... -->
@if (selectedHero(); as s) {
<aside class="panel">
<h3>Selected</h3>
<p>
#{{ s.id }} - {{ s.name }}
@if (s.rank) { <span class="rank">[{{ s.rank }}]</span> }
</p>
<label for="hero-name">Edit name:</label>
<input
id="hero-name"
name="hero-name"
type="text"
placeholder="enter new name"
required
minlength="3"
#nameCtrl="ngModel"
[ngModel]="s.name"
(ngModelChange)="updateName($event)"
[attr.aria-invalid]="nameCtrl.invalid && nameCtrl.touched"
aria-describedby="hero-name-errors" />
@if (nameCtrl.invalid && nameCtrl.touched) {
<ul id="hero-name-errors" class="errors">
@if (nameCtrl.hasError('required')) {
<li>請輸入名稱</li>
}
@if (nameCtrl.hasError('minlength')) {
<li>至少 3 個字</li>
}
</ul>
}
</aside>
}
</section>
<!-- ...existing code... -->
三、新增樣式
// src/app/app.scss
/* ...existing code... */
.errors {
color: #c33;
}
驗收清單:
常見錯誤與排查:
今日小結:
今天在 Selected 區塊中加入 FormsModule 與 ngModel,使選取中的英雄可以編輯,並讓清單與選取畫面實現同步更新。
明天會將建立 HeroService,透過 inject() 依賴注入,學習Angular中服務的使用方法,讓專案更符合實際的架構設計。
參考資料: