[英]Angular - How to close/remove search input when input empty, click outside input element or press esc
I have a search bar that displays results when fed with text input, the problem is:我有一个搜索栏,在输入文本时显示结果,问题是:
this is what the problem looks like: problem这就是问题的样子:问题
components.ts file (removed my failed attempts): components.ts 文件(删除了我失败的尝试):
import {
Component,
OnInit,
Renderer2,
ElementRef,
ViewChild,
} from '@angular/core';
import { faSearch } from '@fortawesome/free-solid-svg-icons';
import { CountryService } from '../services/country.service';
import { OneCountry } from '../country';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css'],
})
export class SearchComponent implements OnInit {
faSearch = faSearch;
countries: OneCountry[] = [];
searchTerm: any;
cachedCountries: OneCountry[] = [];
constructor(private countryService: CountryService) {}
ngOnInit(): void {}
onKeyPressEvent(event: KeyboardEvent): void {
this.getCountries();
}
getCountries(): void {
this.countryService.searchCountries().subscribe({
next: (countries) => (
(this.countries = countries),
(this.cachedCountries = this.countries),
console.log(this.countries)
),
});
}
search(value: string): void {
this.countries = this.cachedCountries.filter((val) =>
val.name.toLowerCase().includes(value)
);
}
}
This is the template file:这是模板文件:
<div id="search-component" class="w-full md:w-[32rem] dark:bg-darkblue-100">
<div
class="w-full px-4 h-[53px] flex justify-around align-center shadow-md border rounded"
>
<figure class="w-1/6 grid place-items-center">
<fa-icon
class="text-darkblue-100 dark:text-white text-lg"
[icon]="faSearch"
></fa-icon>
</figure>
<input
class="w-5/6 h-full focus:outline-none dark:bg-darkblue-100"
placeholder="Search for a country..."
#searchBox
name="searchTerm"
id="search-box"
(input)="search(searchBox.value)"
[(ngModel)]="searchTerm"
(keypress)="onKeyPressEvent($event)"
/>
</div>
<ul class="mt-0 pl-0 relative z-20">
<li
class="z-20"
*ngFor="let country of countries | searchFilter: searchTerm; index as i"
>
<a
*ngIf="i < 10"
routerLink="/detail/{{ country.name }}"
class="z-20 border border-t-0 inline-block w-full md:w-[32rem] p-4 rounded shadow hover:bg-darkblue-100 hover:text-white dark:hover:bg-white dark:hover:text-black h-12 box-border"
>{{ country.name }}</a
>
</li>
</ul>
</div>
"Angular has too many special quirks". “Angular 有太多特殊的怪癖”。 The problem I'm guessing is that your not reseting this.countries back to
[]
.我猜的问题是您没有将 this.countries 重置为
[]
。 You could wire in a blur:您可以模糊地接线:
<input
...
(blur)="onBlur()" />
And then in your class然后在你的 class
onBlur(){
this.countries = [];
}
You should really look into observables though, and as @kinglish mentioned in the comment you have an input and a keypress which is odd.不过,您应该真正研究一下可观察对象,并且正如@kinglish 在评论中提到的那样,您有一个奇怪的输入和一个按键。
Got rid of most of the old stuff and switched to observables.摆脱了大部分旧的东西并切换到可观察的。 Looks like this now:
现在看起来像这样:
Component.ts:组件.ts:
import { Component, OnInit } from '@angular/core';
import { faSearch } from '@fortawesome/free-solid-svg-icons';
import { CountryService } from '../services/country.service';
import { OneCountry } from '../country';
import { Observable, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css'],
})
export class SearchComponent implements OnInit {
faSearch = faSearch;
countries$!: Observable<OneCountry[]>;
private searchTerms = new Subject<string>();
constructor(private countryService: CountryService) {}
// Push a search item into the observable stream
search(term: string): void {
// if (term.length >= 3) {
//
// }
this.searchTerms.next(term);
}
ngOnInit(): void {
this.countries$ = this.searchTerms.pipe(
// Wait 300ms after each keystroke before considering search term
debounceTime(300),
// ignore new term if same as previous term
distinctUntilChanged(),
// Switch to new search observable each time the term changes
switchMap((term: string) => this.countryService.searchCountries(term))
);
}
Search Service:搜索服务:
searchCountries(term: string): Observable<any[]> {
const url = `${this.countriesUrl}all?fields=name`;
if (!term.trim()) {
// If not search term, return empty country list
return of([]);
}
return this.http
.get<Country[]>(url)
.pipe(
map((country) =>
country.filter((val) => val.name.toLowerCase().includes(term))
)
);
}
template:模板:
<div id="search-component" class="w-full md:w-[32rem] dark:bg-darkblue-100">
<div
class="w-full px-4 h-[53px] flex justify-around align-center shadow-md border rounded"
>
<figure class="w-1/6 grid place-items-center">
<fa-icon
class="text-darkblue-100 dark:text-white text-lg"
[icon]="faSearch"
></fa-icon>
</figure>
<input
class="w-5/6 h-full focus:outline-none dark:bg-darkblue-100"
placeholder="Search for a country..."
#searchBox
name="searchTerm"
id="search-box"
(input)="search(searchBox.value)"
/>
</div>
<ul class="mt-0 pl-0 relative z-20">
<li
class="z-20"
*ngFor="
let country of countries$ | async;
index as i;
searchFilter: searchTerms
"
>
<a
*ngIf="i < 10"
routerLink="/detail/{{ country.name }}"
class="z-20 border border-t-0 inline-block w-full md:w-[32rem] p-4 rounded shadow hover:bg-darkblue-100 hover:text-white dark:hover:bg-white dark:hover:text-black"
>{{ country.name }}</a
>
</li>
</ul>
</div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.