我正在尝试使用 flutter bloc 允许用户从下拉菜单中选择员工姓名,然后根据所选员工在同一屏幕上填充表单字段。然后可以编辑这些字段。我已经查看了颤振 todos 示例,它是与我想要做的最接近的功能,但它并不完全相同。
目前,我可以让下拉按钮显示和选择员工对象 (JSON),但我无法根据此选择来填充表单字段。我可以通过状态访问员工对象及其属性,但是当我将变量提供给 TextFormField 的 initialValue 属性时,即使通过控制台打印变量显示它在那里,它也不会显示任何内容。
我一直在尝试对整个屏幕使用一个块来执行此操作,但我现在想知道是否只能使用一个用于下拉按钮的块和另一个用于表单的块来执行此功能。
理想情况下,为了简单起见,我希望在整个屏幕上使用一个块。任何想法如何使用块状态管理根据下拉列表中的选定对象填充表单字段
继承人一些代码:
@override
Widget build(BuildContext context) {
return BlocListener<UpdateEmployeeBloc, UpdateEmployeeState>(
listener: (context, state){
if(state.status.isSubmissionFailure){
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(const SnackBar(content: Text('Creation Failure')));
}
},
child: Align(
alignment: const Alignment(0, -1/3),
child: ListView(
scrollDirection: Axis.vertical,
children: [
const Padding(padding: EdgeInsets.only(top: 250)),
Row(
children: [
Expanded(child: _SelectInput()),
],
),
const Padding(padding: EdgeInsets.all(12)),
Row(
children: [
Expanded(child: _FirstnameInput()),
const Padding(padding: EdgeInsets.all(12)),
Expanded(child: _LastnameInput()),
],
),
const Padding(padding: EdgeInsets.all(12)),
Row(
children: [
Expanded(child:_UsernameInput()),
const Padding(padding: EdgeInsets.all(12)),
Expanded(child:_PasswordInput()),
]
),
const Padding(padding: EdgeInsets.all(12)),
Row(
children: [
Expanded(child: _EmailInput()),
const Padding(padding: EdgeInsets.all(12)),
Expanded(child: _PhonenumberInput()),
]
),
const Padding(padding: EdgeInsets.all(12)),
Row(
children: [
Expanded(child: _JobTitleInput()),
const Padding(padding: EdgeInsets.all(12)),
Expanded(child: _RateInput()),
]
),
const Padding(padding: EdgeInsets.all(20)),
Container(
padding: EdgeInsets.only(left: 100, right:100, ),
child: _UpdateEmployeeButton(),
)
],
),
),
);
}
}
class _SelectInput extends StatelessWidget{
@override
Widget build(BuildContext context) {
final employee_objects = context.select((UpdateEmployeeBloc bloc) => bloc.state.employees);
EmployeeModel? selected_employee;
//context.read<UpdateEmployeeBloc>().add(UpdateEmployeeFormLoaded());
print("Employee Objects");
return BlocBuilder<UpdateEmployeeBloc, UpdateEmployeeState>(
buildWhen: (previous, current) => previous.employees != current.employees,
builder: (context, state){
return DropdownButton<EmployeeModel>(
key: const Key('updateEmployeeForm_selectInput_textfield'),
hint: Text("Choose an Employee"),
value: selected_employee,
items: employee_objects.map<DropdownMenuItem<EmployeeModel>>((EmployeeModel value){
return DropdownMenuItem<EmployeeModel>(
value: value,
child: Text(value.fname + " " + value.lname),
);
}).toList(),
onChanged: (newVal) {
print("In onChanged method");
selected_employee = newVal;
//BlocProvider.of<UpdateEmployeeBloc>(context).add(EmployeeSelected(selected_employee!));
context.read<UpdateEmployeeBloc>().add(EmployeeSelected(selected_employee!));
print("After EmployeeSelected Event");
},
//style: Theme.of(context).textTheme.bodyText1,
);
}
);
}
}
class _FirstnameInput extends StatelessWidget{
const _FirstnameInput({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
String? employee = context.select((UpdateEmployeeBloc bloc) => bloc.state.employee?.fname);
final state = context.watch<UpdateEmployeeBloc>().state;
print("FirstnameInput has been built");
print(state.employee?.fname);
return BlocBuilder<UpdateEmployeeBloc, UpdateEmployeeState>(
buildWhen: (previous, current) => previous.fname != current.fname,
builder: (context, state){
return TextFormField(
key: const Key('createEmployeeForm_firstnameInput_textfield'),
initialValue: employee,
//initialValue: state.employee?.fname,
style: Theme.of(context).textTheme.bodyText1,
onChanged: (fname) => context.read<UpdateEmployeeBloc>().add(FirstnameChanged(fname)),
decoration: InputDecoration(
labelText: 'Firstname',
errorText: state.fname.invalid ? 'Firstname is invalid' : null,
),
);
}
);
}
}
任何帮助,将不胜感激