6 回答
TA贡献1806条经验 获得超8个赞
我认为您需要distinctUntilChanged 并且可以在管道中使用过滤器
this.myService.getDataFromService(data)
.pipe(
filter(_ => data.length === 3),
distinctUntilChanged()
).subscribe(rs => console.log(rs));
TA贡献2037条经验 获得超6个赞
下面是您的代码中的小调整,它将满足您告诉的要求。
您绝对可以使用 debounce、distinctUntilChanged、switchMap 运算符改进此过程。
previousData = '' // create a property which will track of previous data from parent component.
getInputField(data){
if(data && data.length === 3 && data.length > previousData.length){
this.myService.getDataFromService(data).subscribe(rs=>console.log(rs));
}
this.previousData = data || ''; // update previous data to current data after backend call.
}
TA贡献1780条经验 获得超5个赞
使用RxJs FromEvent方法从input字段中监听输入事件。
@ViewChild('#input', {static:true}) inputField: ElementRef<any>;
ngOnInit(){
FromEvent(inputField, 'input')
.pipe(
map(event => event.target.value),
map((value:string) => value.trim()),
filter((value:string) => value.length === 3),
debounceTime(500),
distinctUntilChanged()
)
.subscribe(keyword => {
// API Call(keyword)
})
}
TA贡献1853条经验 获得超9个赞
我制作了一个通用函数,您可以将它用于任意数量的字符以限制您的 API 调用。
const cached = {};
/**
* @desc Check if API call is allowed or not
* based on provided input and length condition
* @param {String} input - input value
* @param {Number} len - length of the input over which API has to be called.
* @returns {Boolean}
*/
function doCallAPI(input, len) {
if(input.length === len) {
if(!cached[input]) {
// Call the API
cached[input] = 1;
return true;
}
}
else if(input.length < len) for(let i in cached) cached[i] = 0;
return false
}
解释:
检查输入的长度是否等于条件长度(此处为 3)。
如果否,则不会为此输入值调用 API。现在,
SET cached[input value] = 1,在缓存对象中插入值。
如果是,则检查缓存的对象是否具有具有输入值的键并且它具有值(例如 1)
返回 true,表示允许调用 API。
检查输入的长度 (Say, 2) 是否小于条件长度。
然后,遍历缓存对象并将所有内容设置为 0,以告知现在允许对条件长度的缓存值进行 API 调用(此处为 3)。
返回 false,告诉 API 调用是不允许的。
这是如何使用它,
getInputField(data){
console.log(data); // this prints the data (Example: abc)
// then here I'm just executing the API call ONLY if data length is 3
if(doCallAPI(data, 3)){
this.myService.getDataFromService(data).subscribe(rs=>console.log(rs));
}
}
TA贡献2065条经验 获得超13个赞
private lastLetter = "";
getInputField(data) {
if(!this.lastLetter === data.toLowerCase()) && data.length === 3) {
this.myService.getDataFromService(data).subscribe(rs=>{
this.lastLetter = data.toLowerCase();
console.log(rs)
});
}
}
我想这行得通
TA贡献1844条经验 获得超8个赞
首先,让我们让您的输入数据可观察 - 以便更容易实现其他一切:
private inputData$ = new Subject<string>();
public getInputField(data: string){
this.inputData$.next(data);
}
现在我们可以用这个输入流做任何我们想做的事。例如,采用上面@Thorsten Rintelen 建议的方法
ngOnInit() {
this.inputData$
.pipe(
filter(data => data.length === 3),
distinctUntilChanged(), // this makes sure api call is sent only if input has changed
switchMap(data => this.myService.getDataFromService(data)),
)
.subscribe(apiResult => console.log(apiResult));
}
注意: 这种方法只缓存最后的输入。如果您想缓存和重用所有 api 响应,您可以将 api 服务方法包装到某个缓存层中,而无需更改任何其他内容。
添加回答
举报