具有 initialData 和 null-awareness 的 Flutter StreamBuilder
Flutter StreamBuilder with initialData and null-awareness
我在理解使用新的 null 感知运算符的 StreamBuilder 时遇到了一些问题。
作为一个学习项目,我正在使用 BloC 模式实施登录流程。对于我的电子邮件登录表单,我创建了一个模型 class,我通过 StreamBuilder 访问它。如果不使用 initialData,snapshot.data 可以为空是完全合理的。但是,将 initialData 设置为预定义的空模型,snapshot.data 永远不会为空,对吧?这是我的代码片段:
@override
Widget build(BuildContext context) {
return StreamBuilder<EmailSignInModel>(
stream: widget.bloc.modelStream,
initialData: EmailSignInModel(),
builder: (context, snapshot) {
final EmailSignInModel model = snapshot.data;
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: _buildChildren(),
),
);
});
}
编译器警告我 snapshot.data 的类型 不等于 。我可以用 snapshot.data ?? EmailSignModel()
解决这个问题,但是这对 initialData 来说是多余的吗?
处理这种情况和处理 Dart 的 null-awareness 的正确方法是什么?
深入研究源代码,我发现了以下内容:
https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/widgets/async.dart
/// The latest data received by the asynchronous computation.
///
/// If this is non-null, [hasData] will be true.
///
/// If [error] is not null, this will be null. See [hasError].
///
/// If the asynchronous computation has never returned a value, this may be
/// set to an initial data value specified by the relevant widget. See
/// [FutureBuilder.initialData] and [StreamBuilder.initialData].
final T? data;
/// Returns latest data received, failing if there is no data.
///
/// Throws [error], if [hasError]. Throws [StateError], if neither [hasData]
/// nor [hasError].
T get requireData {
if (hasData)
return data!;
if (hasError)
throw error!;
throw StateError('Snapshot has neither data nor error');
}
AsyncSnapshot
实际上有一个requireData
getter,这将确保非空或将抛出错误。所以只需将 snapshot.data
替换为 snapshot.requireData
这仍然需要一些手动工作,其中 initialData
和 requireData
的使用需要保持同步。你也可以只使用 snapshot.data!
,它基本上做同样的事情。
我在理解使用新的 null 感知运算符的 StreamBuilder 时遇到了一些问题。
作为一个学习项目,我正在使用 BloC 模式实施登录流程。对于我的电子邮件登录表单,我创建了一个模型 class,我通过 StreamBuilder 访问它。如果不使用 initialData,snapshot.data 可以为空是完全合理的。但是,将 initialData 设置为预定义的空模型,snapshot.data 永远不会为空,对吧?这是我的代码片段:
@override
Widget build(BuildContext context) {
return StreamBuilder<EmailSignInModel>(
stream: widget.bloc.modelStream,
initialData: EmailSignInModel(),
builder: (context, snapshot) {
final EmailSignInModel model = snapshot.data;
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: _buildChildren(),
),
);
});
}
编译器警告我 snapshot.data 的类型 snapshot.data ?? EmailSignModel()
解决这个问题,但是这对 initialData 来说是多余的吗?
处理这种情况和处理 Dart 的 null-awareness 的正确方法是什么?
深入研究源代码,我发现了以下内容:
https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/widgets/async.dart
/// The latest data received by the asynchronous computation.
///
/// If this is non-null, [hasData] will be true.
///
/// If [error] is not null, this will be null. See [hasError].
///
/// If the asynchronous computation has never returned a value, this may be
/// set to an initial data value specified by the relevant widget. See
/// [FutureBuilder.initialData] and [StreamBuilder.initialData].
final T? data;
/// Returns latest data received, failing if there is no data.
///
/// Throws [error], if [hasError]. Throws [StateError], if neither [hasData]
/// nor [hasError].
T get requireData {
if (hasData)
return data!;
if (hasError)
throw error!;
throw StateError('Snapshot has neither data nor error');
}
AsyncSnapshot
实际上有一个requireData
getter,这将确保非空或将抛出错误。所以只需将 snapshot.data
替换为 snapshot.requireData
这仍然需要一些手动工作,其中 initialData
和 requireData
的使用需要保持同步。你也可以只使用 snapshot.data!
,它基本上做同样的事情。