Dart 如何用集团模式管理表单状态?
我目前正在做一个辅助项目,学习Rx和BLoC模式 我想在不使用任何Dart 如何用集团模式管理表单状态?,dart,flutter,bloc,Dart,Flutter,Bloc,我目前正在做一个辅助项目,学习Rx和BLoC模式 我想在不使用任何setState()的情况下管理表单状态 我已经有一个BLoC来管理我的“事件”,这些事件存储在SQLite数据库中,并在验证此表单后添加 我是否需要专门为此UI部件创建一个需求组,以及如何创建?保留这样的代码可以吗?我应该改变我的实际阵营吗 您可以在此处找到我的当前代码: class _EventsAddEditScreenState extends State<EventsAddEditScreen> { bo
setState()
的情况下管理表单状态
我已经有一个BLoC来管理我的“事件”,这些事件存储在SQLite数据库中,并在验证此表单后添加
我是否需要专门为此UI部件创建一个需求组,以及如何创建?保留这样的代码可以吗?我应该改变我的实际阵营吗
您可以在此处找到我的当前代码:
class _EventsAddEditScreenState extends State<EventsAddEditScreen> {
bool hasDescription = false;
bool hasLocation = false;
bool hasChecklist = false;
DateTime eventDate;
TextEditingController eventNameController = new TextEditingController();
TextEditingController descriptionController = new TextEditingController();
@override
Widget build(BuildContext context) {
final eventBloc = BlocProvider.of<EventsBloc>(context);
return BlocBuilder(
bloc: eventBloc,
builder: (BuildContext context, EventsState state) {
return Scaffold(
body: Stack(
children: <Widget>[
Column(children: <Widget>[
Expanded(
child: ListView(
shrinkWrap: true,
children: <Widget>[
_buildEventImage(context),
hasDescription ? _buildDescriptionSection(context) : _buildAddSection('description'),
_buildAddSection('location'),
_buildAddSection('checklist'),
//_buildDescriptionSection(context),
],
))
]),
new Positioned(
//Place it at the top, and not use the entire screen
top: 0.0,
left: 0.0,
right: 0.0,
child: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.check), onPressed: () async{
if(this._checkAllField()){
String description = hasDescription ? this.descriptionController.text : null;
await eventBloc.dispatch(AddEvent(Event(this.eventNameController.text, this.eventDate,"balbla", description: description)));
print('Saving ${this.eventDate} ${eventNameController.text}');
}
},)
],
backgroundColor: Colors.transparent, //No more green
elevation: 0.0, //Shadow gone
),
),
],
),
);
},
);
}
Widget _buildAddSection(String sectionName) {
TextStyle textStyle = TextStyle(
color: Colors.black87, fontSize: 18.0, fontWeight: FontWeight.w700);
return Container(
alignment: Alignment.topLeft,
padding:
EdgeInsets.only(top: 20.0, left: 40.0, right: 40.0, bottom: 20.0),
child: FlatButton(
onPressed: () {
switch(sectionName){
case('description'):{
this.setState((){hasDescription = true;});
}
break;
case('checklist'):{
this.setState((){hasChecklist = true;});
}
break;
case('location'):{
this.setState((){hasLocation=true;});
}
break;
default:{
}
break;
}
},
padding: EdgeInsets.only(top: 0.0, left: 0.0),
child: Text(
'+ Add $sectionName',
style: textStyle,
),
),
);
}
class\u EventsAddEditScreenState扩展状态{
bool hassdescription=false;
bool hasLocation=false;
bool-hasschecklist=false;
日期时间事件日期;
TextEditingController eventNameController=新的TextEditingController();
TextEditingController descriptionController=新建TextEditingController();
@凌驾
小部件构建(构建上下文){
final eventBloc=BlocProvider.of(上下文);
返回BlocBuilder(
集团:事件集团,
生成器:(BuildContext上下文,EventsState状态){
返回脚手架(
主体:堆栈(
儿童:[
栏(儿童:[
扩大(
子:ListView(
收缩膜:对,
儿童:[
_buildEventImage(上下文),
hasDescription?\u buildDescriptionSection(上下文):\u buildAddSection('description'),
_buildAddSection(“位置”),
_buildAddSection(“检查表”),
//_buildDescriptionSection(上下文),
],
))
]),
新定位(
//将其放在顶部,不要使用整个屏幕
排名:0.0,
左:0.0,
右:0.0,
孩子:AppBar(
行动:[
图标按钮(icon:icon(Icons.check),ON按下:()异步{
如果(此.\u checkAllField()){
String description=hasDescription?this.descriptionController.text:空;
wait eventBloc.dispatch(AddEvent(事件(this.eventNameController.text,this.eventDate,“balbla”,description:description));
打印('Saving${this.eventDate}${eventNameController.text}');
}
},)
],
backgroundColor:Colors.transparent,//不再是绿色
标高:0.0,//阴影消失
),
),
],
),
);
},
);
}
小部件_buildAddSection(字符串sectionName){
TextStyle TextStyle=TextStyle(
颜色:Colors.black87,fontSize:18.0,fontWeight:fontWeight.w700);
返回容器(
对齐:alignment.topLeft,
衬垫:
仅限边集(顶部:20.0,左侧:40.0,右侧:40.0,底部:20.0),
孩子:扁平按钮(
已按下:(){
开关(区段名称){
案例(“描述”):{
this.setState((){hassdescription=true;});
}
打破
案例(“清单”):{
this.setState((){hasschecklist=true;});
}
打破
大小写(‘位置’):{
this.setState((){hasLocation=true;});
}
打破
默认值:{
}
打破
}
},
填充:仅限边设置(顶部:0.0,左侧:0.0),
子:文本(
“+添加$sectionName”,
风格:textStyle,
),
),
);
}
让我们一步一步地解决这个问题
你的第一个问题:
我是否需要专门为此UI部件创建需求区?
这与你的需求和你的应用程序有关。如果需要,你可以为每个屏幕设置一个BLoC,但也可以为2或3个小部件设置一个BLoC,这是没有规则的。如果你认为在这种情况下为你的屏幕设置另一个BLoC是一个好方法,因为代码更具可读性、组织性和可伸缩性,你可以这样做或那样做如果你认为这是更好的,只做一个集团与所有内部你也可以自由地这样做
你的第二个问题:怎么做?
在您的代码中,我只看到\u buildAddSection
中的setState
调用,因此,让我们通过编写一个新的BLoc类来改变这一点,并用流处理状态更改
您的\u buildAddSection
中不再有setState
调用。只需更改switch
语句。更改…
调用将更新BLoc类中的流,这将重建侦听流的小部件
switch(sectionName){
case('description'):
bloc.changeDescription(true);
break;
case('checklist'):
bloc.changeChecklist(true);
break;
case('location'):
bloc.changeLocation(true);
break;
default:
// you better do something here!
break;
}
不要忘了调用
bloc.dispose()
你的第一个问题:
我是否需要专门为此UI部件创建需求区?
这与你的需求和你的应用程序有关。如果需要,你可以为每个屏幕设置一个BLoC,但也可以为2或3个小部件设置一个BLoC,这是没有规则的。如果你认为在这种情况下为你的屏幕设置另一个BLoC是一个好方法,因为代码更具可读性、组织性和可伸缩性,你可以这样做或那样做如果你认为这是更好的,只做一个集团与所有内部你也可以自由地这样做
你的第二个问题:怎么做?
在您的代码中,我只看到\u buildAddSection
中的setState
调用,因此,让我们通过编写一个新的BLoc类来改变这一点,并用流处理状态更改
您的\u buildAddSection
中不再有setState
调用。只需更改switch
语句。更改…
调用将更新BLoc类中的流,这将重建侦听流的小部件
switch(sectionName){
case('description'):
bloc.changeDescription(true);
break;
case('checklist'):
bloc.changeChecklist(true);
break;
case('location'):
bloc.changeLocation(true);
break;
default:
// you better do something here!
break;
}
别忘了
switch(sectionName){
case('description'):
bloc.changeDescription(true);
break;
case('checklist'):
bloc.changeChecklist(true);
break;
case('location'):
bloc.changeLocation(true);
break;
default:
// you better do something here!
break;
}