为了账号安全,请及时绑定邮箱和手机立即绑定

在字段中输入3个字符后如何执行API调用?

在字段中输入3个字符后如何执行API调用?

明月笑刀无情 2022-12-22 14:39:58
我正在使用父子组件。子组件有输入字段,并将用户输入的值发送给父组件,如下所示:<parent-component (sendInputValue)="getInputValue($event)"><parent-component>现在在父组件中我有这个: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(data.length === 3){    this.myService.getDataFromService(data).subscribe(rs=>console.log(rs));  }}现在假设发生这种情况:用户输入:abc // API 调用得到执行,这很好现在,用户输入:abcd // 没有 API 调用被执行,这很好现在用户删除字母“d”,数据的新值将是“abc”我不想再次执行 API 调用,因为我们已经执行了“abc”的 API 调用现在,如果用户删除字母“c”,数据的新值现在是“ab”。此时,预计不会有 API 调用现在,如果用户添加字母“c”,新值将是“abc”。此时,API 调用是预期的。(这是有效的)那么,如果输入数据是 3 个字符,并且如果用户输入更多字符,则如何始终执行 API 调用,如果用户删除字符并返回到前 3 个字符,则不应发生任何事情,因为 API 已经发生了?非常感谢!
查看完整描述

6 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

我认为您需要distinctUntilChanged 并且可以在管道中使用过滤器

this.myService.getDataFromService(data)

  .pipe(

    filter(_ => data.length === 3), 

    distinctUntilChanged()

  ).subscribe(rs => console.log(rs));


查看完整回答
反对 回复 2022-12-22
?
阿晨1998

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.

}


查看完整回答
反对 回复 2022-12-22
?
翻阅古今

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)

     })

}


查看完整回答
反对 回复 2022-12-22
?
暮色呼如

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

}

解释:

  1. 检查输入的长度是否等于条件长度(此处为 3)。

    • 如果否,则不会为此输入值调用 API。现在,

    • SET cached[input value] = 1,在缓存对象中插入值。

    • 如果是,则检查缓存的对象是否具有具有输入值的键并且它具有值(例如 1)

    • 返回 true,表示允许调用 API。

  2. 检查输入的长度 (Say, 2) 是否小于条件长度。

  3. 然后,遍历缓存对象并将所有内容设置为 0,以告知现在允许对条件长度的缓存值进行 API 调用(此处为 3)。

  4. 返回 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));

  }

}


查看完整回答
反对 回复 2022-12-22
?
翻翻过去那场雪

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)

        });

      }

    }

我想这行得通


查看完整回答
反对 回复 2022-12-22
?
婷婷同学_

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 服务方法包装到某个缓存层中,而无需更改任何其他内容。


查看完整回答
反对 回复 2022-12-22
  • 6 回答
  • 0 关注
  • 111 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信