问题描述
我有FutureBuilder,它使将来来自HTTP GET请求。轻按提交按钮(也基于isInEditMode bool)初始化Future对象。
- 我第一次点击Submit,它的connectionState从没有变为等待完成。
- 让我们说Future会从Get请求中捕获错误,我可以将其优雅地放入catch块中,我会得到connectionState.done。
- 现在问题出在第二次点击“提交”按钮上,这不会将future的connectionState更新为等待状态,因此,构建器也不会相应地显示在屏幕上。
- 我已经检查过,每次我单击“提交”按钮时,都会从“获取”请求中检索到新的将来对象,但它不会反映在FutureBuilder中。如何让FutureBuilder知道Future对象已更新/更改,以适应新的对象?
class AddEditProductSoScreen extends StatefulWidget {
static const routeName = '/add-edit-product';
@override
_AddEditProductSoScreenState createState() => _AddEditProductSoScreenState();
}
class _AddEditProductSoScreenState extends State<AddEditProductSoScreen> {
var isEditMode = false;
final _formKey = GlobalKey<FormState>();
ProductFormModel _formProduct;
Future<Response> futureOfSubmit;
bool isLoadingVisible = false;
@override
Widget build(BuildContext context) {
final productsProvider =
Provider.of<ProductsProvider>(context,listen: false);
Product product = ModalRoute.of(context).settings.arguments;
if (product != null) {
isEditMode = true;
_formProduct = ProductFormModel.copyFromProduct(product);
} else {
_formProduct = ProductFormModel.init();
}
return Scaffold(
bottomNavigationBar: Container(
height: 50,child: Material(
color: Theme.of(context).accentColor,child: InkWell(
onTap: isLoadingVisible
? null
: () {
if (isEditMode) {
futureOfSubmit =
productsProvider.editProduct(_formProduct);
} else {
futureOfSubmit =
productsProvider.addProduct(_formProduct);
}
isLoadingVisible = true;
futureOfSubmit.then((value) {
//Navigator.of(context).pop();
}).catchError((error) {
showDialog(
context: context,builder: (context) => AlertDialog(
title: Text('An error occurred!'),content: Text('Something went wrong.'),actions: [
FlatButton(
onpressed: () {
Navigator.of(context).pop();
},child: Text('Okay'))
],));
}).whenComplete(() {
setState(() {
isLoadingVisible = false;
});
});
},child: FutureBuilder(
future: futureOfSubmit,builder: (context,AsyncSnapshot<Response> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Align(
alignment: Alignment.center,child: Container(
height: 30,width: 30,child: CircularProgressIndicator(
backgroundColor: Colors.white,)),);
} else {
return Container(
padding: EdgeInsets.all(10),width: double.infinity,child: Text(
'SUBMIT',style: TextStyle(color: Colors.white,fontSize: 20),textAlign: TextAlign.center,),);
}
},);
}
}
任何帮助将不胜感激,谢谢!
编辑:这是productProvider类的addProduct方法,该方法会返回将来的对象,并且也会引发异常。
Future<Response> addProduct(ProductFormModel product) async {
const url = '................';
try {
Response response = await http.post(url,body: json.encode({
'title': product.title,'description': product.description,'imageUrl': product.imageUrl,'price': product.price,'isFavorite': product.isFav
}));
Map respMap = json.decode(response.body);
product.id = respMap['name'];
_items.add(product.toProduct());
notifyListeners();
return response;
} on Exception catch (error) {
print("error is :: " + error.toString());
throw Exception('Something went wrong!!');
}
}
解决方法
要通知框架,小部件的状态已更改,可以使用setState
的{{1}}方法。
所以这个:
StatefulWidget
应为:
futureOfSubmit = productsProvider.editProduct(_formProduct);
然后是其他人。
,使用
setState((){});
通知框架状态已更改。
在If else块中使用setState
setState(() {
futureOfSubmit = productsProvider.editProduct(_formProduct);
});