Flutter 多个bloc:如何嵌套BlocBuilder
我正在设计一个应用程序,其中一个Flutter 多个bloc:如何嵌套BlocBuilder,flutter,Flutter,我正在设计一个应用程序,其中一个BlocBuilder嵌套在另一个BlocBuilder中 将事件分派到嵌套的ServiceBlocbloc时,页面不会按预期刷新:嵌套的BlocBuiler.builder不会触发 这种方法有什么错 下面是一个重现问题的MVCE import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:bloc/bloc.dar
BlocBuilder
嵌套在另一个BlocBuilder
中
将事件分派到嵌套的ServiceBloc
bloc时,页面不会按预期刷新:嵌套的BlocBuiler.builder
不会触发
这种方法有什么错
下面是一个重现问题的MVCE
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:bloc/bloc.dart';
void main() async {
runApp(App());
}
class App extends StatefulWidget {
@override
AppState createState() {
return new AppState();
}
}
// AppBloc states
class ServicePage {}
class SearchState extends ServicePage {}
class AllServices extends ServicePage {}
// end of AppBloc states
// AppBloc events
class AppEvent {}
class EnableSearch extends AppEvent {}
class DisableSearch extends AppEvent {}
// end of AppBloc events
class AppBloc extends Bloc<AppEvent, ServicePage> {
@override
ServicePage get initialState => AllServices();
@override
Stream<ServicePage> mapEventToState(
ServicePage currentState, AppEvent event) async* {
if (event is EnableSearch) {
yield SearchState();
} else {
yield AllServices();
}
}
}
// ServiceBloc events
class ServiceEvent {}
class ServicesLoaded extends ServiceEvent {}
class ServiceFilter extends ServiceEvent {
String pattern;
ServiceFilter(this.pattern);
}
// end of ServiceBloc events
class ServiceBloc extends Bloc<ServiceEvent, List<String>> {
List<String> services = ["aa", "bb", "cc"];
@override
List<String> get initialState => services;
@override
Stream<List<String>> mapEventToState(
List<String> currentState, ServiceEvent event) async* {
if (event is ServiceFilter) {
yield services.where((service) => service.contains(event.pattern));
} else {
yield services;
}
}
}
class AppState extends State<App> {
final TextEditingController _filter = TextEditingController();
final AppBloc appBloc = AppBloc();
final ServiceBloc serviceBloc = ServiceBloc();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: BlocBuilder(
bloc: appBloc,
builder: (BuildContext context, ServicePage sts) {
var searchBar;
if (sts is AllServices) {
searchBar = AppBar(title: const Text('MVCE multi bloc'), actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
appBloc.dispatch(EnableSearch());
},
),
]);
} else {
searchBar = AppBar(
title: TextField(
onSubmitted: (val) {
print("filter string: $val");
serviceBloc.dispatch(ServiceFilter(_filter.text));
},
controller: _filter,
decoration: InputDecoration(
prefixIcon: Icon(Icons.search), hintText: 'Search...'),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () {
serviceBloc.dispatch(ServiceFilter(_filter.text));
appBloc.dispatch(DisableSearch());
}),
]);
}
return Scaffold(
appBar: searchBar,
body: ServicesWidget(serviceBloc));
}),
);
}
}
class ServicesWidget extends StatelessWidget {
final ServiceBloc bloc;
ServicesWidget(this.bloc);
@override
Widget build(BuildContext context) {
return BlocBuilder(
bloc: bloc,
builder: (BuildContext context, List<String> services) {
print("Rebuilding list view");
return ListView.builder(
itemCount: services.length,
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 100,
child: Card(
child: Column(
children: <Widget>[
Text(services[index]),
],
)),
);
});
});
}
}
导入“包装:颤振/材料.省道”;
进口“包装:颤振团/颤振团.飞镖”;
导入“包:bloc/bloc.dart”;
void main()异步{
runApp(App());
}
类应用程序扩展StatefulWidget{
@凌驾
AppState createState(){
返回新的AppState();
}
}
//AppBloc国家
类ServicePage{}
类SearchState扩展ServicePage{}
类AllServices扩展ServicePage{}
//AppBloc状态结束
//AppBloc事件
类AppEvent{}
类EnableSearch扩展了appent{}
类DisableSearch扩展appent{}
//AppBloc事件结束
类AppBloc扩展了Bloc{
@凌驾
ServicePage get initialState=>AllServices();
@凌驾
流映射事件状态(
ServicePage当前状态,AppEvent事件)异步*{
如果(事件为EnableSearch){
屈服状态();
}否则{
产生所有服务();
}
}
}
//服务集团事件
类ServiceEvent{}
类ServicesLoaded扩展ServiceEvent{}
类ServiceFilter扩展ServiceEvent{
字符串模式;
ServiceFilter(此.pattern);
}
//ServiceBloc事件结束
类ServiceBloc扩展了Bloc{
列表服务=[“aa”、“bb”、“cc”];
@凌驾
List get initialState=>services;
@凌驾
流映射事件状态(
列出当前状态、服务事件(事件)异步*{
如果(事件为ServiceFilter){
其中((service)=>service.contains(event.pattern));
}否则{
收益服务;
}
}
}
类AppState扩展了状态{
最终文本编辑控制器_过滤器=文本编辑控制器();
最终AppBloc AppBloc=AppBloc();
最终ServiceBloc ServiceBloc=ServiceBloc();
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。红色,
),
主页:BlocBuilder(
集团:appBloc,
生成器:(BuildContext上下文,ServicePage sts){
var搜索栏;
如果(sts是所有服务){
searchBar=AppBar(标题:const Text('MVCE multi-bloc'),操作:[
图标按钮(
图标:图标(Icons.search),
已按下:(){
appBloc.dispatch(EnableSearch());
},
),
]);
}否则{
searchBar=AppBar(
标题:文本字段(
提交:(val){
打印(“过滤器字符串:$val”);
serviceBloc.dispatch(ServiceFilter(_filter.text));
},
控制器:_过滤器,
装饰:输入装饰(
前缀:Icon(Icons.search),hintText:“search…”,
),
行动:[
图标按钮(
图标:图标(Icons.close),
已按下:(){
serviceBloc.dispatch(ServiceFilter(_filter.text));
appBloc.dispatch(DisableSearch());
}),
]);
}
返回脚手架(
appBar:searchBar,
机构:ServicesWidget(serviceBloc));
}),
);
}
}
类ServicesWidget扩展了无状态小部件{
最终服务集团;
ServicesWidget(this.bloc);
@凌驾
小部件构建(构建上下文){
返回BlocBuilder(
集团:集团,,
生成器:(BuildContext上下文,列出服务){
打印(“重建列表视图”);
返回ListView.builder(
itemCount:services.length,
itemBuilder:(构建上下文,int索引){
返回大小框(
身高:100,
孩子:卡片(
子:列(
儿童:[
文本(服务[索引]),
],
)),
);
});
});
}
}
问题与BlocBuilder的嵌套无关,而是与mapEventToState的实现有关:
Stream<List<String>> mapEventToState(
List<String> currentState, ServiceEvent event) async* {
if (event is ServiceFilter) {
yield services.where((service) => service.contains(event.pattern));
} else {
yield services;
}
}
Stream<List<String>> mapEventToState(
List<String> currentState, ServiceEvent event) async* {
if (event is ServiceFilter) {
yield services.where((service) => service.contains(event.pattern)).toList();
} else {
yield services;
}
}