我正在尝试开发一个TextField,以在它们更改时更新Firestore数据库上的数据。看来可行,但是我需要防止onChange事件触发多次。
在JS中,我会使用lodash _debounce(),但在Dart中,我不知道该怎么做。我读过一些防抖库,但是我不知道它们是如何工作的。
那是我的代码,这只是一个测试,所以可能有些奇怪:
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; class ClientePage extends StatefulWidget { String idCliente; ClientePage(this.idCliente); @override _ClientePageState createState() => new _ClientePageState(); } class _ClientePageState extends State<ClientePage> { TextEditingController nomeTextController = new TextEditingController(); void initState() { super.initState(); // Start listening to changes nomeTextController.addListener(((){ _updateNomeCliente(); // <- Prevent this function from run multiple times })); } _updateNomeCliente = (){ print("Aggiorno nome cliente"); Firestore.instance.collection('clienti').document(widget.idCliente).setData( { "nome" : nomeTextController.text }, merge: true); } @override Widget build(BuildContext context) { return new StreamBuilder<DocumentSnapshot>( stream: Firestore.instance.collection('clienti').document(widget.idCliente).snapshots(), builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) { if (!snapshot.hasData) return new Text('Loading...'); nomeTextController.text = snapshot.data['nome']; return new DefaultTabController( length: 3, child: new Scaffold( body: new TabBarView( children: <Widget>[ new Column( children: <Widget>[ new Padding( padding: new EdgeInsets.symmetric( vertical : 20.00 ), child: new Container( child: new Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ new Text(snapshot.data['cognome']), new Text(snapshot.data['ragionesociale']), ], ), ), ), new Expanded( child: new Container( decoration: new BoxDecoration( borderRadius: BorderRadius.only( topLeft: Radius.circular(20.00), topRight: Radius.circular(20.00) ), color: Colors.brown, ), child: new ListView( children: <Widget>[ new ListTile( title: new TextField( style: new TextStyle( color: Colors.white70 ), controller: nomeTextController, decoration: new InputDecoration(labelText: "Nome") ), ) ] ) ), ) ], ), new Text("La seconda pagina"), new Text("La terza pagina"), ] ), appBar: new AppBar( title: Text(snapshot.data['nome'] + ' oh ' + snapshot.data['cognome']), bottom: new TabBar( tabs: <Widget>[ new Tab(text: "Informazioni"), // 1st Tab new Tab(text: "Schede cliente"), // 2nd Tab new Tab(text: "Altro"), // 3rd Tab ], ), ), ) ); }, ); print("Il widget id è"); print(widget.idCliente); } }
在您的小部件状态中,声明一个控制器和计时器:
final _searchQuery = new TextEditingController(); Timer _debounce;
添加侦听器方法:
_onSearchChanged() { if (_debounce?.isActive ?? false) _debounce.cancel(); _debounce = Timer(const Duration(milliseconds: 500), () { // do something with _searchQuery.text }); }
将方法钩住和解钩到控制器:
@override void initState() { super.initState(); _searchQuery.addListener(_onSearchChanged); } @override void dispose() { _searchQuery.removeListener(_onSearchChanged); _searchQuery.dispose(); _debounce.cancel(); super.dispose(); }
在构建树中,将控制器绑定到TextField:
child: TextField( controller: _searchQuery, // ... )