Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dart 颤振-是否可以不使用FutureBuilder从未来提取数据?_Dart_Flutter - Fatal编程技术网

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;
}
}