Flutter StreamBuilder 与 initialData 和 null-awareness
Posted
技术标签:
【中文标题】Flutter StreamBuilder 与 initialData 和 null-awareness【英文标题】:Flutter StreamBuilder with initialData and null-awareness 【发布时间】:2021-06-24 16:39:44 【问题描述】:我在理解使用新的 null 感知运算符的 StreamBuilder 时遇到了一些问题。
作为一个学习项目,我正在使用 BloC 模式实现登录流程。对于我的电子邮件登录表单,我创建了一个模型类,我可以通过 StreamBuilder 访问它。如果不使用 initialData,snapshot.data 可以为空是完全有意义的。但是,将 initialData 设置为预定义的空模型,snapshot.data 永远不会为空,对吧?这是我的代码 sn-p:
@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 意识的正确方法是什么?
【问题讨论】:
只是想说这是一个非常有趣的问题。事实是 AsyncSnapshot深入研究源代码,我发现了以下内容:
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!
,它的作用基本相同。
【讨论】:
感谢您的明确答复。有趣的是,我距离显示部分答案的文档字符串只有一次 ctrl 单击。总而言之,使用 initialData 不能为空,使用 requireData 是一个很好的解决方案。我也喜欢简单的使用!直接,因为它总是接近于 initialData 参数并明确它不能为空。以上是关于Flutter StreamBuilder 与 initialData 和 null-awareness的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:如何将 StreamBuilder 与 ListView.separated 一起使用
Flutter StreamBuilder 与 initialData 和 null-awareness
FirebaseStorage + Flutter,streamBuilder?