flutter Bloc pattern -- 如何在导航器之后访问 bloc 数据
flutter Bloc pattern -- how to access bloc data after navigator
我有一个包含 2 个页面的应用程序,当主页按钮上的选项卡导航到“设置”页面时。
IconButton(
onPressed:(){
Navigator.push(
context,
MaterialPageRoute( builder: (context) => Settings())
);
},
),
但是在设置页面上,来自我的区块的流数据都是空的。我不知道为什么,在主页上一切都很好。
我在设置页面的 Bloc 中添加了新数据作为测试,它显示正常,所以 Bloc 实现工作正常,只是没有在 bloc 构造函数中获取初始化数据。
我做错了什么?
Bloc 数据在 bloc 构造函数中初始化,这是我的 Bloc 代码
class StateBloc implements BlocBase {
var selectedCurrencies;
StreamController<List> _selectedCurrencies = StreamController<List>.broadcast();
Stream<List> get getSelectedCurrencies => _selectedCurrencies.stream;
StreamSink get modifySelectedCurrencies => _selectedCurrencies.sink;
StateBloc() {
selectedCurrencies = ['cny','aud','usd'];
modifySelectedCurrencies.add(selectedCurrencies);
}
}
以下是如何将 bloc 提供给 main.dart
Future<void> main() async{
return runApp(
BlocProvider<StateBloc>(
child: MyApp(),
bloc: StateBloc(),
),
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Exchange',
debugShowCheckedModeBanner: false,
theme: ThemeData(fontFamily: 'Poppins'),
home: MyHomePage(),
);
}
}
这是我的设置页面
class Settings extends StatelessWidget {
@override
Widget build(BuildContext context) {
final StateBloc appBloc = BlocProvider.of<StateBloc>(context);
return MaterialApp(
home: Scaffold(
body: ListView(
children: <Widget>[
StreamBuilder(
stream: appBloc.getSelectedCurrencies,
builder: (context, selectedCurrenciesSnap) {
print('alllll --> ${allCurrenciesSnap.data}');
}
)
]
)
)
)
}
}
我发现了问题。这是注定要发生的,当构建设置页面中的 StreamBuilder 时,它只监听即将到来的数据,而不是之前的数据。为了得到以前的数据,我们需要重构一些东西。
在 Bloc 中,使用 rxdart 包中的 BehaviorSubject 而不是 streamController,并定义 ValueObservable 而不是 Stream
StreamController _selectedCurrencies = BehaviorSubject();
ValueObservable get getSelectedCurrencies => _selectedCurrencies.stream;
StreamSink get modifySelectedCurrencies => _selectedCurrencies.sink;
然后在“设置”页面中,为 streamBuilder 提供初始数据
initialData: appBloc.getSelectedCurrencies.value,
这个有效:)
我有一个包含 2 个页面的应用程序,当主页按钮上的选项卡导航到“设置”页面时。
IconButton(
onPressed:(){
Navigator.push(
context,
MaterialPageRoute( builder: (context) => Settings())
);
},
),
但是在设置页面上,来自我的区块的流数据都是空的。我不知道为什么,在主页上一切都很好。
我在设置页面的 Bloc 中添加了新数据作为测试,它显示正常,所以 Bloc 实现工作正常,只是没有在 bloc 构造函数中获取初始化数据。
我做错了什么?
Bloc 数据在 bloc 构造函数中初始化,这是我的 Bloc 代码
class StateBloc implements BlocBase {
var selectedCurrencies;
StreamController<List> _selectedCurrencies = StreamController<List>.broadcast();
Stream<List> get getSelectedCurrencies => _selectedCurrencies.stream;
StreamSink get modifySelectedCurrencies => _selectedCurrencies.sink;
StateBloc() {
selectedCurrencies = ['cny','aud','usd'];
modifySelectedCurrencies.add(selectedCurrencies);
}
}
以下是如何将 bloc 提供给 main.dart
Future<void> main() async{
return runApp(
BlocProvider<StateBloc>(
child: MyApp(),
bloc: StateBloc(),
),
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Exchange',
debugShowCheckedModeBanner: false,
theme: ThemeData(fontFamily: 'Poppins'),
home: MyHomePage(),
);
}
}
这是我的设置页面
class Settings extends StatelessWidget {
@override
Widget build(BuildContext context) {
final StateBloc appBloc = BlocProvider.of<StateBloc>(context);
return MaterialApp(
home: Scaffold(
body: ListView(
children: <Widget>[
StreamBuilder(
stream: appBloc.getSelectedCurrencies,
builder: (context, selectedCurrenciesSnap) {
print('alllll --> ${allCurrenciesSnap.data}');
}
)
]
)
)
)
}
}
我发现了问题。这是注定要发生的,当构建设置页面中的 StreamBuilder 时,它只监听即将到来的数据,而不是之前的数据。为了得到以前的数据,我们需要重构一些东西。
在 Bloc 中,使用 rxdart 包中的 BehaviorSubject 而不是 streamController,并定义 ValueObservable 而不是 Stream
StreamController _selectedCurrencies = BehaviorSubject();
ValueObservable get getSelectedCurrencies => _selectedCurrencies.stream;
StreamSink get modifySelectedCurrencies => _selectedCurrencies.sink;
然后在“设置”页面中,为 streamBuilder 提供初始数据
initialData: appBloc.getSelectedCurrencies.value,
这个有效:)