Rxdart combinelaststream 功能不起作用
Posted
技术标签:
【中文标题】Rxdart combinelaststream 功能不起作用【英文标题】:Rxdart combinelaststream function does not work 【发布时间】:2020-05-27 20:40:59 【问题描述】:我将合并两个流。但它不起作用。我的错误是什么?
我的构建函数是 ;
@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;
,
);
Get All DB Accounts Stream Bloc 是
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();
Combiner 结果类是
class AccountsCombinerResult
final DeleteAccountResultBlocModel deleteAccountResultBlocModel;
final List<AccountDatabaseModel> accountsList;
AccountsCombinerResult(
@required this.accountsList,
@required this.deleteAccountResultBlocModel,
);
它的我在 android studio 上运行日志..
I/flutter (28323):帐户获取
I/flutter (28323): hasData : false
I/flutter (28323): hasData : false
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;
,
);
,
);
【问题讨论】:
【参考方案1】:每次调用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,
);
代码未经过测试,因此可能存在拼写错误或我遗漏的内容,但您应该大致了解。
【讨论】:
它不再工作了... StreamProvider 不在flutter/material.dart 包中。 StreamProvider 也是未定义的对象。我尝试了第一个选项,但它不再起作用了。 不起作用没有帮助,StreamProvider
来自提供程序包,您需要将其添加到您的pubspec.yaml
。
我遇到同样的问题,打印(“我的帐户列表:$accountList == null”);这条线没有触发。在 StreamProvider 上没有创建参数。我猜你正在使用旧版本。我的结果是一样的。
我刚刚注意到您删除的流可能没有项目,combineLatest
需要在结果流发出之前发出每个源流。
您可能希望使用BehaviorSubject.seeded(null)
而不是PublishSubject
+ add(null)
。以上是关于Rxdart combinelaststream 功能不起作用的主要内容,如果未能解决你的问题,请参考以下文章