本篇内容为阅读官方文件 Get data from a server 的笔记内容。
接续 Day11 的内容。
这个小节为在某个搜寻栏位输入欲搜寻内容後,程序会将我们输入的内容打出 HTTP 并夹带给服务器端,最後,将相关的搜寻内容送回来给我们,并呈现在画面上。
step 1.
先在 hero.service.ts 档案中,定义一个 http.get
去向服务器要资料的 HTTP 操作。
--- hero.service.ts ---
searchHeroes(term: string): Observable<HERO[]> {
if (!term.trim()) {
return of([]);
}
return this.http.get<HERO[]>(`${this.heroesUrl}/?name=${term}`).pipe(
catchError(this.handleError<HERO[]>('searchHeroes', []))
);
}
以上的内容,就是先去防止输入的查询内容是空白的,最後,把查询内容丢到 http.get
中去查询,查询成功後,就会回传以 Hero 作为资料型别的 Observable 的阵列。
step 2.
接着,新增 hero-search 元件到专案中。
所以,输入指令 ng g c hero-search ,来创出 HeroSearch 元件。
要特别注意的地方是,官方文件中提供的有关 hero-search 元件的 html 的内容,有下列这一段
<div id="search-component">
<label for="search-box">Hero Search</label>
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
<ul class="search-result">
<li *ngFor="let hero of heroes$ | async" >
<a routerLink="/detail/{{hero.id}}">
{{hero.name}}
</a>
</li>
</ul>
</div>
以上这个 ul 元素其实是一个 dropdown menu,将搜寻的结果呈现在这个 menu 上。
在 li 中,利用 *ngFor
来遍历的元素是 heroes$
,在後面加一个钱字号 $
,是要特别声明它是一个 Observable 的实例,不是一个单纯的阵列。
另外,我们在 heroes$ 後面接了一个 async,它其实叫做 asyncPipe,它是专门用来监听一个 Observable 实例是否有变化,并透过 subsrcibe 将该 Observable 实例的最新值传递出来,也因为它将 Observable 的值传递出来,让 *ngFor
可以去遍历它传递出来的内容。
接着,我们就要将寻找的相关英雄内容的功能加到 hero-search 元件中了。
import { Component, OnInit } from '@angular/core';
import { HERO } from '../hero'
import { HeroService } from '../hero.service'
import { Subject, Observable } from 'rxjs'
import {
debounceTime, distinctUntilChanged, switchMap
} from 'rxjs/operators';
@Component({
selector: 'app-hero-search',
templateUrl: './hero-search.component.html',
styleUrls: ['./hero-search.component.css']
})
export class HeroSearchComponent implements OnInit {
heroes$!: Observable<HERO[]>;
private searchTerms = new Subject<string>();
constructor(private heroService:HeroService) {
}
search(term: string): void {
this.searchTerms.next(term);
}
ngOnInit(): void {
this.heroes$ = this.searchTerms.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap((term: string) => this.heroService.searchHeroes(term)),
);
}
}
可以看到 searchTerms 这个变数是 Subject 的实例。
当触发 seatrch 函式的时候,会传入搜寻的英雄名称,接着,在使用 Subject 的 next 方法来呼叫它,并把英雄名称传入,接着,就会进到我们在 ngOnInit 定义的 this.searchTerms.pipe
後面一连串的内容,而在 switchMap 这个 operator 的参数 term 就是我们传入的英雄搜寻名称,最後,再把它丢到 searchHeroes 里面。最终,回传的资料就会存到 this.heroes$ 里面罗。
在以上的程序码中引入了好几个来自 rxjs/operators 的模组,分别是 debounceTime
, distinctUntilChanged
和 switchMap
,会引入它们的原因是因为,要防止当使用者输入搜寻内容的时候,会连续触发 searchHeroes 的事件的状况产生。
debounceTime(300)
: 当使用者超过 300 ms 不再输入之後,就会通过 debounceTime(300)
这关了
distinctUntilChanged
: 若旧值和新值不同的时候,才会通过 distinctUntilChanged
这关
switchMap
: 它会抛弃之前旧的回传值,并接收由最新发出的 HTTP 请求所回传的最新的回传值。
最後,我们将 heroSearch 元件加到 dashBoard 里面。
<h2>Top Heroes</h2>
<div class="heroes-menu">
<a *ngFor="let hero of heroes" (click)="goDetail(hero.id)">
{{ hero.name }}
</a>
</div>
<app-hero-search></app-hero-search>
这边做个总结
*ngFor
可以遍历它。
主题 :从零开始食谱搜寻系统 Day1 (开赛) 开赛宣言 在开赛第一天,icebear希望自己可以...
该文章同步发布於:我的部落格 到了铁人赛的最後一天,看了这麽多东西,我们可以来谈谈学这些测试的好处...
由於感觉我这前几天的文章都字数以及内容都蛮少的,简单来说就只是想低空 飞过,打混过关;结果想透过...
经过了前面几天的基本教学,相信大家都对 Python 有了基本的认识,也应该有点累了,所以今天来讲一...
写在前面 除了 Day 01 的 Tobymini 页面管理,可以和同事之间互相分享网页之外, 有时...