如何在Flutter的InkWell点击事件中更新Firestore卡片数据?
实现Flutter中Firestore数据的更新功能
你已经搞定了数据获取、卡片展示和添加功能,现在要实现点击卡片内的更新图标修改对应Firestore文档的需求,咱们分三步来完成:
1. 添加Firestore数据更新方法
首先在你的crudMedthods类里补充更新逻辑,Firestore更新需要指定目标文档的ID,所以方法要接收文档ID和更新后的数据集:
Future<void> updateData(String docId, Map<String, dynamic> updatedData) async { if (isLoggedIn()) { await Firestore.instance .collection('dis') .document(docId) .updateData(updatedData) .catchError((e) { print(e); }); } else { print('You need to be logged in'); } }
2. 创建预填充数据的更新弹窗
和添加弹窗逻辑类似,但要把当前卡片的现有数据填充到输入框里,方便用户直接修改:
Future<bool> updateDialog(BuildContext context, String docId, Map<String, dynamic> existingData) async { // 用现有数据初始化弹窗变量 DateTime _updateDateTime = existingData['date'] as DateTime; String _updateTemsilci = existingData['temsilci']; String _updateSirano = existingData['sıra no']; String _updateTarih = existingData['tarih']; String _updateVerik = existingData['veri kaynağı']; return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { final _width = MediaQuery.of(context).size.width; return AlertDialog( title: Text('Temsilci Verisi Güncelleyin.', style: GoogleFonts.montserrat( color: Colors.black54, fontSize: 22, fontWeight: FontWeight.w300 ), textAlign: TextAlign.center, ), content: SingleChildScrollView( child: Container( width: _width, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ TextField( onTap: (){ showDatePicker( context: context, initialDate: _updateDateTime, firstDate: DateTime(2000), lastDate: DateTime(2030) ).then((date) { setState(() { _updateDateTime = date!; }); }); }, decoration: InputDecoration(hintText: _updateDateTime.toString()), ), SizedBox(height: 5.0), TextField( decoration: InputDecoration(hintText: 'Temsilci'), controller: TextEditingController(text: _updateTemsilci), onChanged: (value) => _updateTemsilci = value, ), SizedBox(height: 5.0), TextField( decoration: InputDecoration(hintText: 'Sıra No'), controller: TextEditingController(text: _updateSirano), onChanged: (value) => _updateSirano = value, ), SizedBox(height: 5.0), TextField( decoration: InputDecoration(hintText: 'Tarih'), controller: TextEditingController(text: _updateTarih), onChanged: (value) => _updateTarih = value, ), SizedBox(height: 5.0), TextField( decoration: InputDecoration(hintText: 'Veri Kaynağı'), controller: TextEditingController(text: _updateVerik), onChanged: (value) => _updateVerik = value, ), ], ), ), ), actions: <Widget>[ FlatButton( child: Text('İptal'), textColor: Colors.grey, onPressed: () => Navigator.of(context).pop(), ), FlatButton( child: Text('Güncelle'), textColor: Colors.blue, onPressed: () { Navigator.of(context).pop(); // 调用更新方法提交修改 crudObj.updateData(docId, { 'date': _updateDateTime, 'temsilci': _updateTemsilci, 'sıra no': _updateSirano, 'tarih': _updateTarih, 'veri kaynağı': _updateVerik, }).then((result) { dialogTrigger(context); // 用你现有提示弹窗反馈结果 }).catchError((e) => print(e)); }, ) ], ); }); }
3. 在卡片的InkWell中绑定更新弹窗
注意:要确保buildResultCard接收的是Firestore的DocumentSnapshot对象(这样才能拿到文档ID),修改卡片方法并在InkWell的点击事件里调用更新弹窗:
Widget buildResultCard(BuildContext context, DocumentSnapshot data) { return Card( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0)), elevation: 5, child: ExpansionCard( title: Column( children: [ Row( children: [ Padding( padding: EdgeInsets.fromLTRB(5, 0, 5, 1), child: Text( data['isim'], style: GoogleFonts.montserrat( color: Colors.blueGrey[700], fontSize: 20, fontWeight: FontWeight.w400 ), textAlign: TextAlign.center, ), ), Spacer(), // 让更新图标靠右显示 InkWell( child: Icon(Icons.update, color: Colors.blueGrey[700]), onTap: () { // 传入文档ID和现有数据打开更新弹窗 updateDialog(context, data.documentID, data.data()); }, ) ], ), ], ), // 保留你原有ExpansionCard的其他内容 ), ); }
额外小提示
- 构建列表时,要遍历
QuerySnapshot的documents数组,把每个DocumentSnapshot传给buildResultCard,示例:FutureBuilder( future: SearchService().searchByName()[0], builder: (context, snapshot) { if (snapshot.hasData) { return ListView.builder( itemCount: snapshot.data.documents.length, itemBuilder: (context, index) { return buildResultCard(context, snapshot.data.documents[index]); }, ); } else { return CircularProgressIndicator(); } }, ) - 你原
SearchService里的where('no')缺少查询条件,若要获取所有文档可以直接去掉这个语句,避免报错。
内容的提问来源于stack exchange,提问作者user14131906
相关产品推荐
相关产品推荐

