我正在阅读来自TextField
的用户提供的输入(在本例中为邮政编码),我需要检查数据库的有效性。但是,我需要在提交按钮(在本例中为RaisedButton
)onPressed: () {}
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的“口头禅”?我感谢您对此的考虑和意见。
funcThatReturnsFuture().then((result) {
print(result);
setState(() {
someVal = result;
})
})
只是一个方便的助手,可以在Future完成时重建小部件树。
您可以使用
Future funcThatMakesAsyncCall() async {
var result = await funcThatReturnsFuture();
print(result);
setState(() {
someVal = result;
})
}
要么
Future
主要限制是,如果没有Future
,您无法直接将值返回给调用者,因为无法从异步执行返回到同步执行。
我已经想到了这一点(我相信这就是君特最初所说的,但其根本原因当时并不清楚)。能够在不创建Widget
对象的情况下使用Future
的唯一方法是使用Future
API。 Future
API允许解析AsyncSnapshot
对象,好像它是一个.data
对象(这是在FutureBuilder
builder:
函数中解析Future
的地方)。这可以在返回的async
对象上执行(可以使用带有await
的Future 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
的意图相比。很高兴知道这种语言的新手,比如我自己!
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