嵌套的 StreamBuilder 是好的模式吗?
Is nested StreamBuilder good pattern?
我正在使用 Bloc Pattern 和 Streams 从 HackerNews API 获取文章。
我正在加载所有文章并在流生成器的帮助下在 UI 中展示,这工作正常。
现在我用新的加载 StreamBuilder 包装了获取 Stream 构建器的文章。
现在,当加载流生成器为真(意味着它正在加载)时,它会显示一个循环进度指示器,否则,它会显示子项(用流生成器包装的文章列表)。
这很好用。但令我烦恼的是,我已将 Stream Builder 包装在 Stream Builder 中。我知道我可以借助 rxdart,但我不确定如何。
我尝试在 snapshot.hasData 的帮助下添加一个加载器,但没有用,所以我决定创建另一个流和主题,它需要一个 bool 并告诉 UI是否正在加载。
在 bloc 中获取数据的代码:
_getAndUpdateArticles(StoryType storyType) {
_isLoadingSubject.add(true);
getListIds(storyType).then((list) {
getArticles(list.sublist(0, 10)).then((_){
_articleSubject.add(UnmodifiableListView(_articles));
_isLoadingSubject.add(false);
});
});
}
UI:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: StreamBuilder(
stream: widget.hnBloc.isLoading,
builder: (context, snapshot) {
if (snapshot.data) {
return Center(child: CircularProgressIndicator());
} else {
return StreamBuilder<UnmodifiableListView<Article>> (
initialData: UnmodifiableListView<Article>([]),
stream: widget.hnBloc.article,
builder: (context, snapshot) => ListView(
children: snapshot.data.map(_buildItem).toList(),
),
);
}
},
),
.........
编辑
我已经试过了,但是没用:
StreamBuilder<UnmodifiableListView<Article>> (
initialData: UnmodifiableListView<Article>([]),
stream: widget.hnBloc.article,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView(
children: snapshot.data.map(_buildItem).toList(),
);
} else {
return CircularProgressIndicator();
}
}
),
我认为没有避免嵌套 StreamBuilder 的完整方法。我个人认为这不是一个坏习惯,但它肯定会带来更多构建。
在您的情况下,您可以修改 hnBloc 以发出可以是加载状态或数据状态的单一状态,从而消除对嵌套 StreamBuider 的需要。
例如。
StreamBuilder<HnState>(
stream: hnBloc.currentState,
initialData: HnLoadingState(),
builder: (context, snapshot) {
if (snapshot.data is HnLoadingState) {
return Center(child: CircularProgressIndicator());
}if (snapshot.data is HnDataState) {
return ListView(
children: snapshot.data.map(_buildItem).toList(),
),
}
},
)
这种模式在使用 flutter_bloc 包时非常常见。您可以查看此 here 的基本示例以更好地理解它。
我正在使用 Bloc Pattern 和 Streams 从 HackerNews API 获取文章。
我正在加载所有文章并在流生成器的帮助下在 UI 中展示,这工作正常。
现在我用新的加载 StreamBuilder 包装了获取 Stream 构建器的文章。 现在,当加载流生成器为真(意味着它正在加载)时,它会显示一个循环进度指示器,否则,它会显示子项(用流生成器包装的文章列表)。
这很好用。但令我烦恼的是,我已将 Stream Builder 包装在 Stream Builder 中。我知道我可以借助 rxdart,但我不确定如何。
我尝试在 snapshot.hasData 的帮助下添加一个加载器,但没有用,所以我决定创建另一个流和主题,它需要一个 bool 并告诉 UI是否正在加载。
在 bloc 中获取数据的代码:
_getAndUpdateArticles(StoryType storyType) {
_isLoadingSubject.add(true);
getListIds(storyType).then((list) {
getArticles(list.sublist(0, 10)).then((_){
_articleSubject.add(UnmodifiableListView(_articles));
_isLoadingSubject.add(false);
});
});
}
UI:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: StreamBuilder(
stream: widget.hnBloc.isLoading,
builder: (context, snapshot) {
if (snapshot.data) {
return Center(child: CircularProgressIndicator());
} else {
return StreamBuilder<UnmodifiableListView<Article>> (
initialData: UnmodifiableListView<Article>([]),
stream: widget.hnBloc.article,
builder: (context, snapshot) => ListView(
children: snapshot.data.map(_buildItem).toList(),
),
);
}
},
),
.........
编辑
我已经试过了,但是没用:
StreamBuilder<UnmodifiableListView<Article>> (
initialData: UnmodifiableListView<Article>([]),
stream: widget.hnBloc.article,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView(
children: snapshot.data.map(_buildItem).toList(),
);
} else {
return CircularProgressIndicator();
}
}
),
我认为没有避免嵌套 StreamBuilder 的完整方法。我个人认为这不是一个坏习惯,但它肯定会带来更多构建。
在您的情况下,您可以修改 hnBloc 以发出可以是加载状态或数据状态的单一状态,从而消除对嵌套 StreamBuider 的需要。
例如。
StreamBuilder<HnState>(
stream: hnBloc.currentState,
initialData: HnLoadingState(),
builder: (context, snapshot) {
if (snapshot.data is HnLoadingState) {
return Center(child: CircularProgressIndicator());
}if (snapshot.data is HnDataState) {
return ListView(
children: snapshot.data.map(_buildItem).toList(),
),
}
},
)
这种模式在使用 flutter_bloc 包时非常常见。您可以查看此 here 的基本示例以更好地理解它。