如何在Angular 6中的keyup事件中实现去盎司时间
我创建了一个Angular应用程序,可以从API搜索学生。它工作正常,但每次更改输入值时都会调用API。我做了一项研究,我需要一种叫做debounce的东西,但我不知道如何在我的应用程序中实现它 App.component.html如何在Angular 6中的keyup事件中实现去盎司时间,angular,typescript,rxjs,Angular,Typescript,Rxjs,我创建了一个Angular应用程序,可以从API搜索学生。它工作正常,但每次更改输入值时都会调用API。我做了一项研究,我需要一种叫做debounce的东西,但我不知道如何在我的应用程序中实现它 App.component.html <div class="container"> <h1 class="mt-5 mb-5 text-center">Student</h1> <div class="form-group"> <i
<div class="container">
<h1 class="mt-5 mb-5 text-center">Student</h1>
<div class="form-group">
<input class="form-control form-control-lg" type="text" [(ngModel)]=q (keyup)=search() placeholder="Search student by id or firstname or lastname">
</div>
<hr>
<table class="table table-striped mt-5">
<thead class="thead-dark">
<tr>
<th scope="col" class="text-center" style="width: 10%;">ID</th>
<th scope="col" class="text-center" style="width: 30%;">Name</th>
<th scope="col" style="width: 30%;">E-mail</th>
<th scope="col" style="width: 30%;">Phone</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let result of results">
<th scope="row">{{result.stu_id}}</th>
<td>{{result.stu_fname}} {{result.stu_lname}}</td>
<td>{{result.stu_email}}</td>
<td>{{result.stu_phonenumber}}</td>
</tr>
</tbody>
</table>
</div>
屏幕截图
我试过这样的方法,但都是错误的
类型主题上不存在属性debounceTime
这也不管用属性“fromEvent”在类型“typeof Observable”上不存在。
Observable.fromEvent<KeyboardEvent>(this.getNativeElement(this.term), 'keyup')
Observable.fromEvent(this.getNativeElement(this.term),'keyup')
那么,正确的方法是什么呢
谢谢。在组件中,您可以执行类似的操作。创建RxJS
Subject
,在search
方法中(该方法在keyup
事件中调用),对您创建的Subject执行.next()
。然后ngOnInit()
中的subscribe
将debounce
持续1秒,如下代码所示
searchTextChanged = new Subject<string>();
constructor(private http:Http) {
}
ngOnInit(): void {
this.subscription = this.searchTextChanged
.debounceTime(1000)
.distinctUntilChanged()
.mergeMap(search => this.getValues())
.subscribe(() => { });
}
getValues() {
return this.http.get("https://www.example.com/search/?q="+this.q)
.map(
(res:Response) => {
const studentResult = res.json();
console.log(studentResult);
if(studentResult.success) {
this.results = studentResult.data;
} else {
this.results = [];
}
}
)
}
search($event) {
this.searchTextChanged.next($event.target.value);
}
如果您使用的是angular 6和rxjs 6,请尝试以下操作:
请注意订阅之前的.pipe(debounceTime(1000))
import { debounceTime } from 'rxjs/operators';
search() {
this.http.get("https://www.example.com/search/?q="+this.q)
.pipe(debounceTime(1000))
.subscribe(
(res:Response) => {
const studentResult = res.json();
console.log(studentResult);
if(studentResult.success) {
this.results = studentResult.data;
} else {
this.results = [];
}
}
)
}
此外,还可以使用angularformControls绑定输入搜索字段
<input class="form-control form-control-lg"
type="text" [formControl]="searchField"
placeholder="Search student by id or firstname or lastname">
(可选)您可以使用distinctUntilChanged(仅当发布的值不同于上一个值时,才会发布到其输出流)
对于在angular(和rxjs)的更新版本中遇到此问题的任何人
新的Rxjs具有管道操作符,它们可以像这样使用(根据公认的答案代码)
user.component.html
<input type="text" #userNameRef class="form-control" name="userName" > <!-- template-driven -->
<form [formGroup]="regiForm">
email: <input formControlName="emailId"> <!-- formControl -->
</form>
*注意:确保您的输入元素不在ngIf块中。演示
教程来源
使用模板变量
<input type="text" #movieSearchInput class="form-control" placeholder="Type any movie name" />
...
...
fromEvent(this.movieSearchInput.nativeElement, 'keyup').pipe(
// get value
map((event: any) => {
return event.target.value;
})
// if character length greater then 2
,filter(res => res.length > 2)
// Time in milliseconds between key events
,debounceTime(1000)
// If previous query is diffent from current
,distinctUntilChanged()
// subscription for response
).subscribe((text: string) => {
this.isSearching = true;
this.searchGetCall(text).subscribe((res)=>{
console.log('res',res);
this.isSearching = false;
this.apiResponse = res;
},(err)=>{
this.isSearching = false;
console.log('error',err);
});
});
...
...
...
...
fromEvent(this.movieSearchInput.nativeElement,'keyup').pipe(
//获得价值
地图((事件:任意)=>{
返回event.target.value;
})
//如果字符长度大于2
,过滤器(res=>res.length>2)
//关键事件之间的时间(毫秒)
,去BounceTime(1000)
//如果上一个查询与当前查询不同
,distinctUntilChanged()
//订阅以获取响应
).订阅((文本:字符串)=>{
this.isSearching=true;
this.searchGetCall(text).subscribe((res)=>{
console.log('res',res);
this.isSearching=false;
this.apiResponse=res;
},(错误)=>{
this.isSearching=false;
console.log('error',err);
});
});
...
...
像这样使用,不带RXJS
它可能会在每次键控时调用“search()”函数本身,但不会每次都调用函数的内部内容(如http connect)。非常简单的解决方案
export class MyComponent implements OnInit {
debounce:any;
constructor(){}
search(){
clearTimeout(this.debounce);
this.debounce = setTimeout(function(){
// Your Http Function..
},500); // Debounce time is set to 0.5s
}
}
仍然存在一个错误属性“debounceTime”在的类型“Subject”上不存在。debounceTime(1000)
这是我的新代码@mongkonsrisin,rxjs v6有几个突破性的更改,包括简化操作员的导入点。尝试安装rxjs compat
,这将添加回那些导入路径,直到代码被迁移。安装rxjs compat后,该错误消失,但在this处有另一个错误。getValues(search)
应为0个参数,但得到1@mongkonsrisin,很抱歉,在ngOnInit
this.getValues(搜索)中
应该是this.getValues()
,因为它不需要任何参数。我已经更新了answerIt's still error参数的类型'(search:string)=>void'不可分配给参数的类型'(value:string,index:number)=>ObservableInput)。这在任何情况下都不会解决keyup事件way@Logus在对问题的描述中,这家伙问他需要实现一个叫做去BounceTime的东西,但他不知道如何实现。@NadhirFalta,这个标题实际上提到他想在keyup事件中实现去BounceTime。@Logus问题描述中是这样说的:“我做了一项研究,我需要一种叫做debounce的东西,但我不知道如何在我的应用程序中实现它。”这个实现并不完整,但这是答案.pipe(debounceTime(1000))中的关键部分
结合已接受的答案,使用RxJs解决了我的issueCheck Angular Input DebounceTime示例。首先,在我的ngOnInit()方法中未定义@ViewChild。因此,我在ngAfterViewInit()中添加了整个fromEvent。但是,当我键入输入时,在第一个键控中,我的订阅事件仅在第一个类型中调用,而在我再次键入时不会调用。
searchField: FormControl;
ngOnInit() {
this.searchField.valueChanges
.debounceTime(5000)
.subscribe(term => {
// call your service endpoint.
});
}
searchField: FormControl;
ngOnInit() {
this.searchField.valueChanges
.debounceTime(5000)
.distinctUntilChanged()
.subscribe(term => {
// call your service endpoint.
});
}
ngOnInit() {
this.subscription = this.searchTextChanged.pipe(
debounceTime(1000),
distinctUntilChanged(),
mergeMap(search => this.getValues())
).subscribe((res) => {
console.log(res);
});
<input type="text" #userNameRef class="form-control" name="userName" > <!-- template-driven -->
<form [formGroup]="regiForm">
email: <input formControlName="emailId"> <!-- formControl -->
</form>
import { fromEvent } from 'rxjs';
import { switchMap,debounceTime, map } from 'rxjs/operators';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
constructor(private userService : UserService) { }
@ViewChild('userNameRef') userNameRef : ElementRef;
emailId = new FormControl();
regiForm: FormGroup = this.formBuilder.group({
emailId: this.bookId
});
ngOnInit() {
fromEvent(this.userNameRef.nativeElement,"keyup").pipe(
debounceTime(3000),
map((userName : any) =>userName.target.value )
).subscribe(res =>{
console.log("User Name is :"+ res);
} );
//--------------For HTTP Call------------------
fromEvent(this.userNameRef.nativeElement,"keyup").pipe(
debounceTime(3000),
switchMap((userName : any) =>{
return this.userService.search(userName.target.value)
})
).subscribe(res =>{
console.log("User Name is :"+ res);
} );
----------
// For formControl
this.emailId.valueChanges.pipe(
debounceTime(3000),
switchMap(emailid => {
console.log(emailid);
return this.userService.search(emailid);
})
).subscribe(res => {
console.log(res);
});
}
<input type="text" #movieSearchInput class="form-control" placeholder="Type any movie name" />
...
...
fromEvent(this.movieSearchInput.nativeElement, 'keyup').pipe(
// get value
map((event: any) => {
return event.target.value;
})
// if character length greater then 2
,filter(res => res.length > 2)
// Time in milliseconds between key events
,debounceTime(1000)
// If previous query is diffent from current
,distinctUntilChanged()
// subscription for response
).subscribe((text: string) => {
this.isSearching = true;
this.searchGetCall(text).subscribe((res)=>{
console.log('res',res);
this.isSearching = false;
this.apiResponse = res;
},(err)=>{
this.isSearching = false;
console.log('error',err);
});
});
...
...
export class MyComponent implements OnInit {
debounce:any;
constructor(){}
search(){
clearTimeout(this.debounce);
this.debounce = setTimeout(function(){
// Your Http Function..
},500); // Debounce time is set to 0.5s
}
}