angular - mat-autocomplete 多次调用服务器而不是一次
问题描述
当我键入几个字母时,它应该执行 GET 请求并自动完成返回的 JSON 对象。出于某种原因,我可以从我的 nodejs 控制台中看到,在我停止输入几秒钟而不是一次之后,它会像 3 次一样击中后端。(我有一个延迟计时器,用于检查用户是否完成输入)我的代码有什么问题?
<div id="userSearch">
<mat-form-field class="formFields" id="username1Field" [ngStyle]="{'font-size.px': 12}" appearance="outline">
<mat-label id="placeholder">Sender</mat-label>
<input type="text" placeholder="Find User" name="username1" aria-label="Number" matInput [formControl]="myControl"
(keyup)="onKeySearch($event)" [matAutocomplete]="auto" required>
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let option of posts" [value]="option.username">
{{option.username}}
</mat-option>
</mat-autocomplete>
<mat-error>User Invalid</mat-error>
</mat-form-field>
</div>
零件
import { Component, OnInit, OnDestroy, ViewChild } from "@angular/core";
import { AuthService } from "../auth.service";
import { Router } from "@angular/router";
import { MessagingService } from "../message-table/messaging.service";
import { FormControl } from "@angular/forms";
import { SubmitListingService } from "../submit-listing/submit-auction.service";
import { takeUntil } from "rxjs/operators";
import { Subject } from "rxjs";
import { FindUserModel } from "../header/user-search.model";
import { Complaint } from "../message-table/complaint.model";
import { MatTableDataSource, MatSort } from "@angular/material";
@Component({
selector: "admin-analyzer",
templateUrl: "./admin-analyzer.component.html",
styleUrls: ["./admin-analyzer.component.css"]
})
export class AdminAnalyzerComponent implements OnInit, OnDestroy {
constructor(
private authService: AuthService,
private router: Router,
private messagingService: MessagingService,
private submitListingService: SubmitListingService
) {}
dataSource: MatTableDataSource<any> = new MatTableDataSource();
userId: string;
myControl = new FormControl();
posts: FindUserModel[] = [];
destroy = new Subject();
timeout;
getData = false;
isLoading = false;
currentPage = 1;
searchedUserId: string;
messages: Complaint[];
foundUser = false;
totalPosts: number;
displayedColumns = ["defendant", "userThatSubmitted", "creationDate"];
@ViewChild(MatSort, { static: false }) set sort(sort: MatSort) {
this.dataSource.sort = sort;
}
ngOnInit() {
this.userId = this.authService.getUserId();
}
readMessage(
id: string,
recipient: string,
creatorName: string,
creatorId: string
) {
this.router.navigate(["/read-message", id], { skipLocationChange: true });
}
getComplaints() {
this.isLoading = true;
this.messagingService
.getComplaints(this.searchedUserId, this.currentPage)
.subscribe(res => {
console.log(res);
this.totalPosts = res.maxPosts;
this.messages = res.posts;
this.dataSource.data = this.messages;
this.isLoading = false;
this.getData = true;
});
}
private onKeySearch(event: any) {
var $this = this;
this.timeout = setTimeout(function() {
if (event.keyCode !== 13) {
$this.executeListing(event.target.value);
}
}, 2000);
for (const post of this.posts) {
if (event.target.value === post.username) {
console.log("ITS A MATCH!");
this.foundUser = true;
this.searchedUserId = post.id;
console.log("searchedUserId2");
console.log(this.searchedUserId);
this.posts = [];
}
}
}
private executeListing(userSearched: string) {
if (userSearched === "[Object object]") {
return;
}
console.log(userSearched);
if (userSearched.length > 2) {
this.submitListingService
.getUserIdAutoComplete(userSearched, this.userId)
.pipe(takeUntil(this.destroy))
.subscribe(res => {
console.log("res");
console.log(res);
this.posts = res.posts;
console.log(this.posts);
});
}
}
ngOnDestroy() {
clearTimeout(this.timeout);
this.destroy.next();
this.destroy.complete();
}
}
解决方案
您将onKeySearch
侦听器附加到keyup
事件,这意味着每次按键都会触发以下代码:
this.timeout = setTimeout(function() {
if (event.keyCode !== 13) {
$this.executeListing(event.target.value);
}
}, 2000);
在创建新的超时之前,您需要清除已经存在的超时。即使this.timeout
被覆盖,也只是超时 ID,而不是超时本身。
clearTimeout(this.timeout);
this.timeout = setTimeout(function() {
if (event.keyCode !== 13) {
$this.executeListing(event.target.value);
}
}, 2000);
推荐阅读
- oop - 抽象工厂模式是否有“更多”真实世界的例子?
- json - 为什么我的 jq / read / echo 管道会删除反斜杠?
- c++ - 获取包含字符和整数的字符串并分别使用它们 C++
- android - 快速滚动后,BottomSheetDialogFragment 内的 RecyclerView 项目需要双击
- javascript - 使用 Helmet 嵌入第三方聊天小部件
- tcp - Windows 应用程序 TCP 有效负载 (md5) 可以复制吗?
- git - 使用 git rm 命令删除 .gitignore 中列出的文件
- reactjs - Amplify Authenticator 显示不需要的问候语
- javascript - JavaScript EventSource 监听 Webhook 推送到 PHP 脚本
- ajax - 使用 Javascript 从远程 EC2 实例读取文件?