颤动:根据Future的快照采取行动

时间:2017-10-18 00:24:32

标签: dart flutter

我在尝试Flutter时遇到了一个我无法弄清楚的问题。我正在考虑的案例中有一个FutureBuilder小部件,如下所示:

 @override
    Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Example Page"),
        ),
        body: new FutureBuilder(
            future: _exampleFuture,
            builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.waiting: return new Center(child: new CircularProgressIndicator(),);
                default:
                  if(snapshot.hasError) {
                    return new Center(child: new Text('Error: ${snapshot.error}'),);
                  }
                  else {
                    return new Center(child: new Text("Result: ${snapshot.data}"),);
                  }
              }
            }
        )
    );
  }

现在让我们假设未来是一个http调用,结果是401错误,表明用户未经授权。此时,我希望应用程序删除存储的任何令牌并重定向到登录页面或只是重建应用程序。但我不能调用在构建函数中执行此操作的方法,并且我不认为didUpdateWidget()被保证被调用,因为未来可能会在调用build之前返回它的值?也许我接近这个完全错误,但有没有办法在Flutter中做到这一点?

1 个答案:

答案 0 :(得分:4)

您可以在statusCode方法中检查Async,并使用setState根据statusCode值删除令牌的值;否则,如果连接已获得授权,则返回所需数据。现在,在FutureBuilder中,检查您的快照是否为空,以显示SignIn()页面。

例如,处理http请求的方法可能类似于:

_Request() async {
    var httpClinet = createHttpClient();
    var response = await httpClinet.get(
        url, headers: {'Authorization': "Bearer $_currentUserToken"});
    if (response.statusCode == 200) {
      var myRequest = JSON.decode(response.body);
      var myDesiredData;

      ///TODO: Some data conversions and data extraction
      return myDesiredData;
    }
    else {
      setState(() {
        _currentUserToken = null;
      });
      return null;

       }
}

然后你可以拥有这样的FutureBuilder:

@override
  Widget build(BuildContext context) {
    return new FutureBuilder(future: _request(),
        builder: (BuildContext context, AsyncSnapshot response) {
          response.hasData==false? new SignIn(): new Scaffold(
            appBar: new AppBar(title: new Text("Future Builder"),),
            body: new Center(
              child: new Text("Build your widgets"),
            ),
          );
    }
      );
}