Dart 颤振-是否可以不使用FutureBuilder从未来提取数据?
我从一个Dart 颤振-是否可以不使用FutureBuilder从未来提取数据?,dart,flutter,Dart,Flutter,我从一个TextField中读取用户提供的输入(在本例中为邮政编码),我需要对照数据库检查输入的有效性。但是,我需要在submit按钮的内部进行异步数据库查询(在本例中是RaisedButton)onPressed:(){}lambda函数。在大多数编程语言中,这是一项相当直接和简单的任务。然而,我在flatter中遇到的问题是,从异步数据库查询返回的Future对象只能被FutureBuilder对象使用,而这些对象又只能返回Widget对象。我只需要返回一个字符串,然后我就可以使用它通过Ma
TextField
中读取用户提供的输入(在本例中为邮政编码),我需要对照数据库检查输入的有效性。但是,我需要在submit按钮的内部进行异步数据库查询(在本例中是RaisedButton
)onPressed:(){}
lambda函数。在大多数编程语言中,这是一项相当直接和简单的任务。然而,我在flatter中遇到的问题是,从异步数据库查询返回的Future
对象只能被FutureBuilder
对象使用,而这些对象又只能返回Widget
对象。我只需要返回一个字符串
,然后我就可以使用它通过MaterialPageRoute
对象传递到新路由,或者在不更改路由的情况下向用户显示错误。有没有办法用颤振来做这个?返回一个小部件对我来说是无用的,因为我不想创建一个新的小部件来显示。我使用的是颤振0.3.2和飞镖2.0.0
作为需要调用数据库查询的简化示例:
@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
}
}
}
),
],
);
}
@覆盖
小部件构建(构建上下文){
返回新列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
新容器(
填充:常数边集全部(16.0),
孩子:新文本字段(
键盘类型:TextInputType.number,
控制器:_控制器,
装饰:新的输入装饰(
hintText:'邮政编码',
),
提交:(字符串){
返回字符串;
},
),
),
新升起的按钮(
已按下:(){
//使用regex根据用户输入进行测试
if(_controller.text!=null&&u controller.text.isNotEmpty){
RegExp-zipCodeRegExp=newregexp(r“^(\d{5})$”);
//如果用户输入验证。。。
if(zipCodeRegExp.hasMatch(_controller.text)){
zipCode=_controller.text;
//需要在此处执行数据库查询并返回字符串,而不是小部件
}否则{
//这里还有一个条件
}
}否则{
//这里还有一个条件
}
}
}
),
],
);
}
也许我没有遵循弗利特的“咒语”?我感谢您在这方面的考虑和投入。
FutureBuilder
只是一个方便的助手,可以在将来完成时重建小部件树
你可以用
funcThatReturnsFuture().then((result) {
print(result);
setState(() {
someVal = result;
})
})
或
主要的限制是,如果没有
未来
,您无法直接将值返回给调用方,因为无法从异步执行返回到同步执行。a未来
只是回调的语义糖。想象一下你有:
void fetchName(void Function(String) callback);
void main() {
fetchName((name) {
print('Your name is: $name');
});
}
无法从fetchName
转换(或提取)name
。它在回调完成之前不存在,回调可能不会立即完成(可以从数据库读取,如您的示例或网络等)
使用它的一个优点是,它确实有助于理解异步抽象,如Future
(以及Stream
),并让您专注于编写(同步)构建器代码:
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}');
}
},
)
new FutureBuilder(
future:_计算,//future或null
生成器:(BuildContext上下文,异步快照){
交换机(快照.连接状态){
case ConnectionState.none:返回新文本(“按下按钮开始”);
case ConnectionState.waiting:返回新文本('waiting result…');
违约:
if(snapshot.hasError)
返回新文本('Error:${snapshot.Error}');
其他的
返回新文本('Result:${snapshot.data}');
}
},
)
我后来明白了这一点(我相信这就是甘特最初所说的,但当时我不清楚的根本原因)。能够使用未来
而不创建小部件
对象的唯一方法是使用未来
API。Future
API允许解析Future
对象,就像解析AsyncSnapshot
对象一样(在FutureBuilder
函数中解析.data
)。这可以在返回的Future
对象上执行(该对象可以使用async
和wait
)。例如:
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 regionName=dbClient.getRegionNameFromZipCode(int.parse(zipCode)) 您可以创建两种方法,一种用于提取放入变量中的数据,另一种类似于getter(在我的情况下,我需要使用plugin flatter\u secure\u存储访问安全值,而不使用Futurebuilder)
mixinSecureStorageMethods{
字符串键值;
Future\u getFromSecureStorage(字符串键)异步{
keyValue=wait slL().read(key:key);
返回键值;
}
字符串getSecureValue(字符串键){
_getFromSecureStorage(密钥);
返回键值;
}
}
是的,我很感激,但如果我只是创建一个FutureBuilder对象实例,它本身就会返回一个小部件。那么,在不将小部件本身返回为父小部件的一部分的情况下,如何从中获取快照数据呢?如果您不想构建小部件,我不明白为什么您需要一个构建器(无论是哪种类型的构建器),我需要同步而不是异步查询,以便获得除未来之外的返回类型?这是我不需要小部件的解决方案吗?你不能通过网络访问服务器
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);
});
mixin SecureStorageMethods {
String keyValue;
Future<String> _getFromSecureStorage(String key) async {
keyValue = await slL<FlutterSecureStorage>().read(key: key);
return keyValue;
}
String getSecureValue(String key) {
_getFromSecureStorage(key);
return keyValue;
}
}