如何在Flutter Widget渲染前调用Cloud Firestore拉取数据填充表单
解决方案
核心问题是Firestore.get()是异步操作,你原来的同步执行逻辑会在请求返回前就完成页面渲染,后续_editedMeal赋值没有触发组件重绘,所以会出现空白。可以按照以下步骤修改:
步骤1:修改didChangeDependencies中的异步逻辑
把静态数据获取替换为异步请求,请求过程中开启加载状态,拿到数据后调用setState触发重绘:
@override void didChangeDependencies() { if (_isInit == true) { final mealId = widget.id; if (mealId != null) { // 开启加载状态 setState(() { _isLoading = true; }); // 发起Firestore异步请求 FirebaseFirestore.instance.collection('meals').doc(mealId).get().then((DocumentSnapshot document) { if (document.exists) { // 解析数据赋值 _editedMeal = Meal( id: document.id, title: document.get('title'), recipe: document.get('recipe'), description: document.get('description'), imageUrl: document.get('imageUrl'), // 其他字段按需补充 ); // 初始化表单值 _initValues = { 'title': _editedMeal.title, 'recipe': _editedMeal.recipe, 'description': _editedMeal.description, 'imageUrl': '', }; _imageUrlController.text = _editedMeal.imageUrl; } // 关闭加载状态,触发重绘 setState(() { _isLoading = false; }); }).catchError((error) { // 可自行添加错误处理逻辑,比如弹出错误提示 setState(() { _isLoading = false; }); }); } else { // 新增餐品的场景,直接初始化空表单即可 _isLoading = false; } } _isInit = false; super.didChangeDependencies(); }
步骤2:修改build方法适配加载状态
在页面渲染逻辑中先判断加载状态,数据未返回时显示加载占位,避免空白表单:
@override Widget build(BuildContext context) { return _isLoading ? const Center(child: CircularProgressIndicator()) // 加载中显示进度圈 : /* 你原来的表单Widget代码 */; }
可选优化
如果希望打开表单时看不到加载过程,可以在上一层网格页点击编辑按钮时,先预加载Firestore数据,等数据拿到后再打开底部表单,这样进入表单页可以直接渲染数据。
内容的提问来源于stack exchange,提问作者Tammo
相关产品推荐
相关产品推荐

