TextField на изменения, вызов API - как это дросселировать? - PullRequest
0 голосов
/ 19 февраля 2019

Если у меня есть текстовое поле и при изменении в этом текстовом поле я вызываю функцию, которая вызывает API, как я могу ее ограничить, поэтому она вызывает эту функцию, только если пользователь ничего не набрал в течение 1 секунды?

Я потерян здесь ... любая помощь более чем приветствуется.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Используйте Timer.

Если клавиша нажата до одной секунды, отмените старый таймер и перенесите его с новым таймером, в противном случае выполните вызов API:

import 'dart:async';

class _MyHomePageState extends State<MyHomePage> {
  String textValue;
  Timer timeHandle;

  void textChanged(String val) {
    textValue = val;
    if (timeHandle != null) {
      timeHandle.cancel();
    }  
    timeHandle = Timer(Duration(seconds: 1), () {
      print("Calling now the API: $textValue");
    });
  }

  @override
  void dispose() {
      super.dispose();
      timeHandle.cancel();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Container(
              padding: EdgeInsets.all(20),
              alignment: Alignment.center,
              child: TextField(
                onChanged: textChanged,
                  decoration: InputDecoration(
                      border: InputBorder.none,
                      hintText: 'Please enter a search term')),
            ),
          ],
        ),
      ),
    );
  }
}
0 голосов
/ 19 февраля 2019

Вам необходимо использовать класс с именем CancelableOperation из асинхронного пакета .

Вы можете объявить его в виджете с отслеживанием состояния вне метода build():

CancelableOperation cancelableOperation;

И используйте его в своем обратном вызове onChanged:

cancelableOperation?.cancel();

cancelableOperation = CancelableOperation.fromFuture(Future.delayed(Duration(seconds: 1), () {
  // API call here
}));
...