flutter - Rxdart combinelaststream 功能不起作用
问题描述
我将合并两个流。但它不起作用。我的错误是什么?
我的构建功能是;
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Observable.combineLatest2(
getAllDBAccountsBloc.getAllDBAccountsStream,
deleteDBAccountBloc.deleteDBAccountStream,
(accountList, deleteAccountResultModel) {
print("my account list : ${accountList == null}");
return AccountsCombinerResult(
deleteAccountResultBlocModel: deleteAccountResultModel,
accountsList: accountList,
);
},
),
builder: (context, snapshot) {
print("hasData : ${snapshot.hasData}");
if (snapshot.hasData) accountsCombinerResult = snapshot.data;
if (snapshot.hasError) return Text(snapshot.error.toString());
return _buildWidget;
},
);
}
获取所有数据库帐户流块是
class GetAllDBAccountsBloc {
final _getAllDBAccountsFetcher = PublishSubject<List<AccountDatabaseModel>>();
Observable<List<AccountDatabaseModel>> get getAllDBAccountsStream => _getAllDBAccountsFetcher.stream;
getAllDBAccounts() async {
print("accounts getting");
_getAllDBAccountsFetcher.sink.add(null);
await new Future.delayed(const Duration(seconds: 1));
_getAllDBAccountsFetcher.sink.add(await Repository.getAllDBAccounts());
print("accounts get");
}
dispose() {
_getAllDBAccountsFetcher.close();
}
}
final getAllDBAccountsBloc = GetAllDBAccountsBloc();
删除数据库帐户块现为
class DeleteDBAccountBloc {
final _deleteDBAccountFetcher = PublishSubject<DeleteAccountResultBlocModel>();
Observable<DeleteAccountResultBlocModel> get deleteDBAccountStream => _deleteDBAccountFetcher.stream;
deleteDBAccount(DeleteAccountRequestBlocModel requestModel) async {
_deleteDBAccountFetcher.sink.add(DeleteAccountResultBlocModel());
await new Future.delayed(const Duration(seconds: 1));
_deleteDBAccountFetcher.sink.add(await Repository.deleteDBAccount(requestModel));
}
dispose() {
_deleteDBAccountFetcher.close();
}
}
final deleteDBAccountBloc = DeleteDBAccountBloc();
组合器结果类是
class AccountsCombinerResult {
final DeleteAccountResultBlocModel deleteAccountResultBlocModel;
final List<AccountDatabaseModel> accountsList;
AccountsCombinerResult({
@required this.accountsList,
@required this.deleteAccountResultBlocModel,
});
}
它的我在 android studio 上运行日志..
I/flutter (28323):账户获取
我/颤振(28323):hasData:假
我/颤振(28323):hasData:假
I/flutter (28323):帐户获取
流工作,但我没有得到 AccountsCombiner 结果数据。
这种构建方法有效,但我不想使用它......
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: getAllDBAccountsBloc.getAllDBAccountsStream,
builder: (context, getDbAccountsSnapshot) {
return StreamBuilder(
stream: deleteDBAccountBloc.deleteDBAccountStream,
builder: (context, deleteDbAccountStreamSnapshot) {
if (deleteDbAccountStreamSnapshot.hasData && getDbAccountsSnapshot.hasData) {
print("qweqweq");
accountsCombinerResult = AccountsCombinerResult(
accountsList: getDbAccountsSnapshot.data,
deleteAccountResultBlocModel: deleteDbAccountStreamSnapshot.data,
);
}
if (getDbAccountsSnapshot.hasError) return Text(getDbAccountsSnapshot.error.toString());
if (deleteDbAccountStreamSnapshot.hasError) return Text(deleteDbAccountStreamSnapshot.error.toString());
return _buildWidget;
},
);
},
);
}
解决方案
每次build
调用该方法时,您都在构建一个新流。您需要将流引用保持在状态。
StreamController<AccountsCombinerResult> _streamController = StreamController<AccountsCombinerResult>();
@override
void initState() {
super.initState();
_streamController.addStream(Observable.combineLatest2(
getAllDBAccountsBloc.getAllDBAccountsStream,
deleteDBAccountBloc.deleteDBAccountStream,
(accountList, deleteAccountResultModel) {
print("my account list : ${accountList == null}");
return AccountsCombinerResult(
deleteAccountResultBlocModel: deleteAccountResultModel,
accountsList: accountList,
);
},
));
}
@override
void dispose() {
super.dispose();
_streamController.close();
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _streamController.stream,
builder: (context, snapshot) {
print("hasData : ${snapshot.hasData}");
if (snapshot.hasData) accountsCombinerResult = snapshot.data;
if (snapshot.hasError) return Text(snapshot.error.toString());
return _buildWidget;
},
);
}
为了使这更容易,您可以使用StreamProvider
提供程序包中的 。
https://pub.dev/packages/provider
https://pub.dev/documentation/provider/latest/provider/StreamProvider-class.html
它只构建一次流。
@override
Widget build(BuildContext context) {
return StreamProvider<AccountsCombinerResult>(
initialData: null, // not sure if this works, you can try []
create: () => Observable.combineLatest2(
getAllDBAccountsBloc.getAllDBAccountsStream,
deleteDBAccountBloc.deleteDBAccountStream,
(accountList, deleteAccountResultModel) {
print("my account list : ${accountList == null}");
return AccountsCombinerResult(
deleteAccountResultBlocModel: deleteAccountResultModel,
accountsList: accountList,
);
},
),
catchError: (context, error) => AccountsCombinerResult(
deleteAccountResultBlocModel: null,
accountsList: null,
error: error,
),
child: Builder(
builder: (context) {
final data = Provider.of<AccountsCombinerResult>(context);
// maybe null check
if (data.error != null) return Text(data.error.toString());
accountsCombinerResult =data;
return _buildWidget;
},
),
);
}
class AccountsCombinerResult {
final DeleteAccountResultBlocModel deleteAccountResultBlocModel;
final List<AccountDatabaseModel> accountsList;
final dynamic error;
AccountsCombinerResult({
@required this.accountsList,
@required this.deleteAccountResultBlocModel,
this.error,
});
}
该代码未经过测试,因此可能存在拼写错误或我遗漏的内容,但您应该了解总体思路。
推荐阅读
- crystal-lang - 哈希.包括?在晶体中产生奇怪的结果
- angular - 登录侧菜单不显示
- docker - 带有构建参数的 ENTRYPOINT 和 CMD
- javascript - AngularJS - 从 ng-repeat 获取当前对象
- php - 如果值相同,如何对 SQL 查询结果进行排序?
- amazon-web-services - aws - 存在分区时如何创建请求
- html - 将图像部分定位在页面底部之外
- angular - 角 2 | 无法分配给变量,因为它是常量或只读属性
- scala - 如何展平 Spark 数据集中的嵌套字段?
- android-studio - android构建gradle错误(android 3.1.3)?连接超时:连接