1

我有 FutureBuilder,它需要来自 HTTP GET 请求的未来。Future 对象在点击提交按钮时被初始化,这也是基于 isInEditMode 布尔值。

  • 我第一次点击提交时,它的连接状态从无变为等待按预期完成。
  • 假设未来从 Get 请求中捕获错误,我可以优雅地将其放入 catch 块中,我得到了 connectionState.done,这很好。
  • 现在问题出现在提交按钮的第二次点击上,它不会将未来的连接状态更新为等待,反过来,构建器不会在屏幕上相应地显示。
  • 我检查过,每次点击提交按钮时,都会从 Get 请求中检索全新的未来对象,但它不会反映在 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!!');
    }
  }
4

2 回答 2

1

要通知框架,您的小部件的状态已更改,您可以setState使用StatefulWidget.

所以这:

futureOfSubmit = productsProvider.editProduct(_formProduct);

应该:

setState(() { futureOfSubmit = productsProvider.editProduct(_formProduct); });

和其他相应的。

于 2020-09-28T14:48:56.537 回答
1

利用

setState((){});

通知框架,状态已经改变。

在 If else 块中使用 setState

setState(() {
futureOfSubmit = productsProvider.editProduct(_formProduct);
 });
于 2020-09-28T15:46:41.570 回答