Angular
前言
- 因為項目需求,需要實現一個搜索功能,之前看Angular官方文檔的時候,記得有相同的實現,也沒多想,心想著既然是官方文檔,應該代碼質量也是有保證的,所以就照著官方例子寫了。然而,事情并沒有想象中那么簡單。
1.代碼
- HTML代碼(文檔中的例子):
<div id="search-component">
<h4>Hero Search</h4>
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<div>
<div *ngFor="let hero of heroes | async"
(click)="gotoDetail(hero)" class="search-result" >
{{hero.name}}
</div>
</div>
</div>
- TS部分代碼:
search(term: string): void {
this.searchTerms.next(term);
}
ngOnInit(): void {
this.heroes = this.searchTerms
.debounceTime(300) // wait 300ms after each keystroke before considering the term
.distinctUntilChanged() // ignore if next search term is same as previous
.switchMap(term => term // switch to new observable each time the term changes
// return the http search observable
? this.heroSearchService.search(term)
// or the observable of empty heroes if there was no search term
: Observable.of<Hero[]>([]))
.catch(error => {
// TODO: add real error handling
console.log(error);
return Observable.of<Hero[]>([]);
});
}
2.問題
- 實例代碼中實現的功能是在搜索框中輸入搜索條件,觸發一個keyup事件即可通過HTTP發送搜索請求,不像之前項目中的搜索,輸入完搜索條件還需要點擊搜索按鈕,這也算是Angular數據綁定好處吧。
- 但是,真相是綁定的(keyup)事件并沒有每次都按照預期的運行,在測試功能的過程中,居然發現輸入值后搜索不了,一檢查keyup事件居然沒有觸發,雖然概率大概是20%左右,但是出了問題總要解決啊。
3.解決方案
- 然后就去Stack Overflow上尋找答案,居然還真有,解決方法在此,本來還以為是自己代碼寫的有問題,然而并不是。
- 解決方案:
// HTML
<input [(ngModel)]="searchBox" id="search-box" (keyup)="search(event)"/>
// Compoenet
searchBox: string // declare before constructor into your component
// declare after constructor into your component
@HostListener('document:keyup', ['$event'])
search(event: KeyboardEvent): void {
this.searchTerms.next(this.searchBox);
}
- 解釋一下,該解決方案的意思是,把搜索框的值進行雙向綁定,然后使用一個HostListener來監聽文檔中的keyup事件,就是每次觸發keyup事件都調用search()函數,按照解決方法試了一下,發現真的可以,按道理應該到此就圓滿結束。
- 但是并沒有,填完一個坑總是又有一個新的坑。正如上文所言,上述解決方案中的HostListener是用來監聽整個文檔中的keyup事件,這就很尷尬了,項目需求中是同一個頁面中兩個搜索框,只要任何有一個keyup觸發,都會調用該搜索功能,這他么還得力,每次keyup事件調用一次,這顯然是一個更大的坑啊!
- 好憂桑,怎么辦,如何解決?
4.最終解決方案:
- 后來想了想,算了吧,這個綁定keyup事件功能就不用了,不就是輸入完自動搜索嘛,不要了。果斷加了個搜索按鈕,然后綁定(click)事件,每次輸入完畢后去點一下,實現完畢之后測試了幾十次,發現果然沒有再出現不能觸發事件的問題了。
總結
- 寫代碼還是要自己動手實踐,實踐中遇到問題是好事情,通過解決這些問題,才能鍛煉和提升自身能力。
- 前端Angular打怪升級中,業余寫寫學習筆記,記錄并分享學習心得,歡迎騷擾討論技術問題。