嵌套两个流构建器导致错误状态错误
Posted
技术标签:
【中文标题】嵌套两个流构建器导致错误状态错误【英文标题】:Nesting two stream builders causing bad state error 【发布时间】:2020-10-12 13:01:12 【问题描述】:我正在从两个不同的 Firestore 集合中获取数据,这是我的代码
StreamBuilder(
stream: Firestore.instance.collection('items').snapshots(),
builder: (BuildContext context, snapshot)
if(snapshot.connectionState == ConnectionState.waiting)
return CupertinoActivityIndicator();
if(snapshot.data != null)
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context,index)
return Column(
children: <Widget>[
Text(snapshot.data.documents[index]['name']),
Text(snapshot.data.documents[index]['color']),
Text(snapshot.data.documents[index]['lifetime']),
Container(
child: StreamBuilder(
stream: Firestore.instance.collection('users')
.document(userid).collection('Quantity')
.document(snapshot.data.documents[index]['id']).snapshots(),
builder: (BuildContext context, snap)
if(snapshot.connectionState == ConnectionState.waiting)
return CupertinoActivityIndicator();
if(snap.data != null)
return Container(
child: Text(snap.data.documents.length)
);
,
),
)
],
);
);
,
)
它给了我错误,但是当我在 streambuilder 中使用 futurebuilder 时一切正常,我也使用了流广播,但它也给了我同样的错误。 这是我用于广播流的代码
StreamController _controller = StreamController.broadcast();
Stream getItems() async*
Firestore.instance.collection('items').snapshots().listen((data)
_controller.add(data);
)
yield* _controller.stream;
【问题讨论】:
【参考方案1】:您不应在 StreamBuilder
内创建新的 Stream
。当你这样做时:
StreamBuilder(
stream: Firestore.instance.collection('items').snapshots(),
和
StreamBuilder(
stream: Firestore.instance.collection('users')
.document(userid).collection('Quantity')
.document(snapshot.data.documents[index]['id']).snapshots(),
每次调用build()
函数时都会创建一个新的StreamBuilder
,因此会调用Firestore.instance.collection()...snapshots()
,每次都返回一个新的Stream
。
您应该将您的小部件转换为StatefulWidget
并在initState()
上初始化您的Stream
,将其作为类变量传递给您的StreamBuilder
。嵌套的StreamBuilder
也可以转换为StatefulWidget
并就地创建,但以相同的方式初始化。请注意,您可能需要Key
才能在ListView
上正确显示它。
此外,如果您想将单个订阅 Stream
转换为广播 Stream
,您只需调用 asBroadcastStream
即可进行转换。
【讨论】:
非常感谢现在一切正常,但是使用这种方法,我的代码看起来比嵌套流构建器更复杂。我仍然不明白为什么直接向流构建器提供流会出错? 我认为这与共享相同上下文的 2 个 StreamBuilders 有关,因此当外部的发出时,内部的会使用相同的上下文重新创建,因此它可能正在获取对旧流的引用以进行订阅。这可能会重复到 StreamBuilder 逻辑上处理正在传递的新旧流,必须进行更深入的调查。以上是关于嵌套两个流构建器导致错误状态错误的主要内容,如果未能解决你的问题,请参考以下文章