Angular的搜索查询没有随着用户输入而更新
我在做一个针对动物园的Angular项目,练习使用RXJS。当用户进行搜索或输入按键时,先延时几毫秒再进行搜索,这样就不会在每次按键时都触发搜索。
然后再对已通过fetch获得的列表进行过滤。
不过我发现结果似乎滞后一个按键。
也就是说,例如有一个包含 { Leo, Lane, John } 的小名单。
我在搜索框中输入L 时,全部三个仍然显示。接着输入La(本应只显示Lane),结果Leo和 Lane都出现了(这和只输入L 时应该发生的行为不符)。
然后我输入Lan,只有Lane显示。
我想让搜索框在每次按键时就更新,不要滞后一个按键。
HTML:
@for (animal of userAnimals; track animal) {
<mat-card class="card" appearance="outlined" style="margin: 10px;">
<mat-card-header>
<img
#animalIMG
src="A-Cat.jpg"
class="card-img-top animalImage"
alt="..."
[id]="animal.species"
(load)="loadImage(animalIMG.id)"
style="height: 200px"
/>
</mat-card-header>
<mat-card-title>{{ animal.name }} The {{ animal.species }}</mat-card-title>
<mat-card-content>
@if (animal.openStatus) {
<p class="bg-success-subtle">{{ animal.name }} Is open</p>
} @else {
<p class="bg-warning-subtle">{{ animal.name }} Is Closed</p>
}
</mat-card-content>
</mat-card>
grid-view.ts:
searchSubjet$ = new Subject<string>();
public animals: IAnimal[] = [];
public userAnimals: IAnimal[] = [];
public searchString!: string;
// Inject the list of animals
constructor(
private animalListService: Animalslist,
private notifyService: NotificationService,
private cdr: ChangeDetectorRef,
) {
afterNextRender(() => {
this.notifyService.enableNotifications();
});
}
public async ngAfterViewInit(): Promise<void> {
this.searchSubjet$.pipe(debounceTime(500)).subscribe((userSearch) => {
console.log(userSearch);
if (userSearch === '' || userSearch === null) {
this.userAnimals = this.animals;
} else {
this.userAnimals = this.animals.filter((a) =>
a.name.toUpperCase().startsWith(userSearch.toUpperCase()),
);
}
this.cdr.detectChanges();
});
}
public async ngOnInit() {
// Get the list of animals.
// This list can be iterated over to make a proper grid view of animals.
this.animals = await this.animalListService.getAll();
this.userAnimals = this.animals;
// https://stackoverflow.com/questions/34364880/expression-has-changed-after-it-was-checked
// this.cdr.detectChanges();
}
public inputChanged($event: any) {
this.searchSubjet$.next($event.srcElement.value);
}
解决方案
通常你会使用RxJS的 debounce、FormControl和 asyncPipe
search=new FormControl()
animals$=search.valueChanges.pipe(
startsWith(null),
debounceTime(200),
map((search:string)=> {
return !x?this.animals:
this.animals.filter(x=>a.name.toUpperCase()
.startsWith(userSearch.toUpperCase())
}))
并使用
<input [formControl]="search"/>
@for (animal of animals$|async; track animal)
{
...
}
要使用signal,请查看 此链接
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。