Flutter - 是否可以在不使用FutureBuilder的情况下从Future中提取数据?

问题描述 投票:5回答:3

我正在阅读来自TextField的用户提供的输入(在本例中为邮政编码),我需要检查数据库的有效性。但是,我需要在提交按钮(在本例中为RaisedButtononPressed: () {} lambda函数内部进行异步数据库查询。在大多数编程语言中,这是一项相当简单和简单的任务。然而,我在Flutter中遇到的问题是,从异步数据库查询返回的Future对象只能由FutureBuilder对象使用,而Widget对象只返回String对象。我只需要返回一个MaterialPageRoute,然后我可以使用它通过@override Widget build(Buildcontext context) { return new Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ new Container( padding: const EdgeInsets.all(16.0), child: new TextField( keyboardType: TextInputType.number, controller: _controller, decoration: new InputDecoration( hintText: 'Zip Code', ), onSubmitted: (string) { return string; }, ), ), new RaisedButton( onPressed: () { // use regex to test against user input if (_controller.text != null && _controller.text.isNotEmpty) { RegExp zipCodeRegExp = new RegExp(r"^(\d{5})$"); // if the user input validates... if (zipCodeRegExp.hasMatch(_controller.text)) { zipCode = _controller.text; // need to perform database query here and return a string, not a Widget } else { // an else condition here } } else { // an else condition here } } } ), ], ); } 对象传递到新路径,或者在不改变路径的情况下向用户显示错误。 Flutter有没有办法做到这一点?返回Widget对我来说没用,因为我不想创建一个新的Widget来显示。我正在使用Flutter 0.3.2和Dart 2.0.0

作为我需要调用数据库查询的简化示例:

FutureBuilder

也许我不是在跟随Flutter的“口头禅”?我感谢您对此的考虑和意见。

dart flutter
3个回答
7
投票

funcThatReturnsFuture().then((result) { print(result); setState(() { someVal = result; }) }) 只是一个方便的助手,可以在Future完成时重建小部件树。

您可以使用

Future funcThatMakesAsyncCall() async {
  var result = await funcThatReturnsFuture();
  print(result);  
  setState(() {
    someVal = result;
  })
}

要么

Future

主要限制是,如果没有Future,您无法直接将值返回给调用者,因为无法从异步执行返回到同步执行。


2
投票

我已经想到了这一点(我相信这就是君特最初所说的,但其根本原因当时并不清楚)。能够在不创建Widget对象的情况下使用Future的唯一方法是使用Future API。 Future API允许解析AsyncSnapshot对象,好像它是一个.data对象(这是在FutureBuilder builder:函数中解析Future的地方)。这可以在返回的async对象上执行(可以使用带有awaitFuture regionName = dbClient.getRegionNameFromZipCode(int.parse(zipCode)); <-- this database method getRegionNameFromZipCode returns a Future object and uses async and await regionName.then((data) { String hZonesString = data[0]['hzone']; print(hZonesString); }, onError: (e) { print(e); }); )。例如:

Future

一旦你理解了如何利用FutureBuilder API,这是相当简单的,并且它与使用Future的意图相比。很高兴知道这种语言的新手,比如我自己!


1
投票

void fetchName(void Function(String) callback); void main() { fetchName((name) { print('Your name is: $name'); }); } 只是回调的语义糖。想象一下你有:

name

没有办法从fetchName转换(或提取)FutureBuilder。它在回调完成之前不存在,并且回调可能不会立即完成(可以从数据库中读取,例如您的示例或网络等)。

使用Future的一个优点是它真的有助于理解异步抽象,如StreamBuilder(和Stream for new FutureBuilder<String>( future: _calculation, // a Future<String> or null builder: (BuildContext context, AsyncSnapshot<String> snapshot) { switch (snapshot.connectionState) { case ConnectionState.none: return new Text('Press button to start'); case ConnectionState.waiting: return new Text('Awaiting result...'); default: if (snapshot.hasError) return new Text('Error: ${snapshot.error}'); else return new Text('Result: ${snapshot.data}'); } }, ) ),并让你专注于编写(同步)构建器代码:

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.