這堂教學課程示範如何為你的 Angular 應用程式加上搜尋功能。
應用程式會讓使用者搜尋應用程式提供的資料,並且只顯示與輸入字詞相符的結果。
IMPORTANT: 本教學的這個步驟,建議你在本機環境操作。
你會學到什麼
- 你的應用程式會使用表單的資料,搜尋相符的住房地點
- 你的應用程式只會顯示相符的住房地點
-
更新首頁元件的屬性
在這個步驟中,你會更新
Home類別,把資料存放在一個新的陣列屬性中,用來進行篩選。在
src/app/home/home.ts中,為類別加上一個名為filteredLocationList的新屬性。在 home.ts 中加入 filteredLocationList 屬性
import {ChangeDetectorRef, Component, inject} from '@angular/core'; import {HousingLocation} from '../housing-location/housing-location'; import {HousingLocationInfo} from '../housinglocation'; import {HousingService} from '../housing-service'; @Component({ selector: 'app-home', imports: [HousingLocation], template: ` <section> <form> <input type="text" placeholder="Filter by city" #filter /> <button class="primary" type="button" (click)="filterResults(filter.value)">Search</button> </form> </section> <section class="results"> @for (housingLocation of filteredLocationList; track $index) { <app-housing-location [housingLocation]="housingLocation" /> } </section> `, styleUrl: './home.css', }) export class Home { private readonly changeDetectorRef = inject(ChangeDetectorRef); housingLocationList: HousingLocationInfo[] = []; housingService: HousingService = inject(HousingService); filteredLocationList: HousingLocationInfo[] = []; constructor() { this.housingLocationList = this.housingService.getAllHousingLocations(); this.filteredLocationList = this.housingLocationList; } filterResults(text: string) { if (!text) { this.filteredLocationList = this.housingLocationList; return; } this.filteredLocationList = this.housingLocationList.filter((housingLocation) => housingLocation?.city.toLowerCase().includes(text.toLowerCase()), ); } }filteredLocationList存放與使用者輸入的搜尋條件相符的值。頁面載入時,
filteredLocationList預設應該包含全部的住房地點值。請更新Home的constructor來設定這個值。設定 filteredLocationList 的值
import {ChangeDetectorRef, Component, inject} from '@angular/core'; import {HousingLocation} from '../housing-location/housing-location'; import {HousingLocationInfo} from '../housinglocation'; import {HousingService} from '../housing-service'; @Component({ selector: 'app-home', imports: [HousingLocation], template: ` <section> <form> <input type="text" placeholder="Filter by city" #filter /> <button class="primary" type="button" (click)="filterResults(filter.value)">Search</button> </form> </section> <section class="results"> @for (housingLocation of filteredLocationList; track $index) { <app-housing-location [housingLocation]="housingLocation" /> } </section> `, styleUrl: './home.css', }) export class Home { private readonly changeDetectorRef = inject(ChangeDetectorRef); housingLocationList: HousingLocationInfo[] = []; housingService: HousingService = inject(HousingService); filteredLocationList: HousingLocationInfo[] = []; constructor() { this.housingLocationList = this.housingService.getAllHousingLocations(); this.filteredLocationList = this.housingLocationList; } filterResults(text: string) { if (!text) { this.filteredLocationList = this.housingLocationList; return; } this.filteredLocationList = this.housingLocationList.filter((housingLocation) => housingLocation?.city.toLowerCase().includes(text.toLowerCase()), ); } }
-
更新首頁元件的範本
Home已經有一個輸入欄位,你會用它來取得使用者的輸入。那串文字會用來篩選結果。更新
Home範本,在input元素中加入一個名為#filter的範本變數。在 home.ts 的 input HTML 元素中加入範本變數
import {ChangeDetectorRef, Component, inject} from '@angular/core'; import {HousingLocation} from '../housing-location/housing-location'; import {HousingLocationInfo} from '../housinglocation'; import {HousingService} from '../housing-service'; @Component({ selector: 'app-home', imports: [HousingLocation], template: ` <section> <form> <input type="text" placeholder="Filter by city" #filter /> <button class="primary" type="button" (click)="filterResults(filter.value)">Search</button> </form> </section> <section class="results"> @for (housingLocation of filteredLocationList; track $index) { <app-housing-location [housingLocation]="housingLocation" /> } </section> `, styleUrl: './home.css', }) export class Home { private readonly changeDetectorRef = inject(ChangeDetectorRef); housingLocationList: HousingLocationInfo[] = []; housingService: HousingService = inject(HousingService); filteredLocationList: HousingLocationInfo[] = []; constructor() { this.housingLocationList = this.housingService.getAllHousingLocations(); this.filteredLocationList = this.housingLocationList; } filterResults(text: string) { if (!text) { this.filteredLocationList = this.housingLocationList; return; } this.filteredLocationList = this.housingLocationList.filter((housingLocation) => housingLocation?.city.toLowerCase().includes(text.toLowerCase()), ); } }本範例使用範本參考變數來取得
input元素,把它當作值來存取。接著,更新元件範本,為 "Search" 按鈕加上事件處理器。
在 home.ts 中把按鈕的 click 事件繫結到方法
import {ChangeDetectorRef, Component, inject} from '@angular/core'; import {HousingLocation} from '../housing-location/housing-location'; import {HousingLocationInfo} from '../housinglocation'; import {HousingService} from '../housing-service'; @Component({ selector: 'app-home', imports: [HousingLocation], template: ` <section> <form> <input type="text" placeholder="Filter by city" #filter /> <button class="primary" type="button" (click)="filterResults(filter.value)">Search</button> </form> </section> <section class="results"> @for (housingLocation of filteredLocationList; track $index) { <app-housing-location [housingLocation]="housingLocation" /> } </section> `, styleUrl: './home.css', }) export class Home { private readonly changeDetectorRef = inject(ChangeDetectorRef); housingLocationList: HousingLocationInfo[] = []; housingService: HousingService = inject(HousingService); filteredLocationList: HousingLocationInfo[] = []; constructor() { this.housingLocationList = this.housingService.getAllHousingLocations(); this.filteredLocationList = this.housingLocationList; } filterResults(text: string) { if (!text) { this.filteredLocationList = this.housingLocationList; return; } this.filteredLocationList = this.housingLocationList.filter((housingLocation) => housingLocation?.city.toLowerCase().includes(text.toLowerCase()), ); } }透過繫結
button元素上的click事件,你就可以呼叫filterResults函式。傳給這個函式的引數,是filter範本變數的value屬性,具體來說就是inputHTML 元素的.value屬性。範本的最後一項更新是
@for指令。請更新@for,讓它逐一處理filteredLocationList陣列中的值。更新 home.ts 中的 @for 範本指令
import {ChangeDetectorRef, Component, inject} from '@angular/core'; import {HousingLocation} from '../housing-location/housing-location'; import {HousingLocationInfo} from '../housinglocation'; import {HousingService} from '../housing-service'; @Component({ selector: 'app-home', imports: [HousingLocation], template: ` <section> <form> <input type="text" placeholder="Filter by city" #filter /> <button class="primary" type="button" (click)="filterResults(filter.value)">Search</button> </form> </section> <section class="results"> @for (housingLocation of filteredLocationList; track $index) { <app-housing-location [housingLocation]="housingLocation" /> } </section> `, styleUrl: './home.css', }) export class Home { private readonly changeDetectorRef = inject(ChangeDetectorRef); housingLocationList: HousingLocationInfo[] = []; housingService: HousingService = inject(HousingService); filteredLocationList: HousingLocationInfo[] = []; constructor() { this.housingLocationList = this.housingService.getAllHousingLocations(); this.filteredLocationList = this.housingLocationList; } filterResults(text: string) { if (!text) { this.filteredLocationList = this.housingLocationList; return; } this.filteredLocationList = this.housingLocationList.filter((housingLocation) => housingLocation?.city.toLowerCase().includes(text.toLowerCase()), ); } }
-
實作事件處理器函式
範本已經更新,把
filterResults函式繫結到click事件。接下來,你的任務是在Home類別中實作filterResults函式。更新
Home類別,加入filterResults函式的實作。加入 filterResults 函式的實作
import {ChangeDetectorRef, Component, inject} from '@angular/core'; import {HousingLocation} from '../housing-location/housing-location'; import {HousingLocationInfo} from '../housinglocation'; import {HousingService} from '../housing-service'; @Component({ selector: 'app-home', imports: [HousingLocation], template: ` <section> <form> <input type="text" placeholder="Filter by city" #filter /> <button class="primary" type="button" (click)="filterResults(filter.value)">Search</button> </form> </section> <section class="results"> @for (housingLocation of filteredLocationList; track $index) { <app-housing-location [housingLocation]="housingLocation" /> } </section> `, styleUrl: './home.css', }) export class Home { private readonly changeDetectorRef = inject(ChangeDetectorRef); housingLocationList: HousingLocationInfo[] = []; housingService: HousingService = inject(HousingService); filteredLocationList: HousingLocationInfo[] = []; constructor() { this.housingLocationList = this.housingService.getAllHousingLocations(); this.filteredLocationList = this.housingLocationList; } filterResults(text: string) { if (!text) { this.filteredLocationList = this.housingLocationList; return; } this.filteredLocationList = this.housingLocationList.filter((housingLocation) => housingLocation?.city.toLowerCase().includes(text.toLowerCase()), ); } }這個函式使用
Array的filter函式,把text參數的值與housingLocation.city屬性互相比較。你可以更新這個函式,讓它比對任何屬性、甚至多個屬性,作為一個有趣的練習。儲存你的程式碼。
重新整理瀏覽器,輸入文字並點選 "Search" 按鈕後,確認你可以依城市搜尋住房地點資料。

SUMMARY: 在本課中,你使用範本變數與範本值互動,並運用事件繫結與陣列函式新增搜尋功能。
想進一步了解本課介紹的主題,請造訪: