【发布时间】:2021-11-15 21:40:36
【问题描述】:
我想实现什么?
我正在为我的身份验证组件使用 Flutter BLoc 库。在登录页面内,我有一些文本字段,例如用户名/密码,我也将与其他页面共享,例如注册页面、忘记密码、更改密码等。基本上,遵循 DRY 原则.
每个页面(注册、登录、忘记密码等)都有自己的 BLoc 组件。
我的问题 我找不到将小部件与 BLoc 分离的方法。我希望能够在有状态小部件中传递任何 BLoc 组件,具体取决于它所使用的页面。
为了理解上面的内容,让我们看看我的代码。
login.dart 来自登录页面的 build 方法的一段代码。
Widget _loginForm(){
return BlocListener<LoginBloc, LoginState>(
listener: (context, state) {
final status = state.formStatus;
if (status is SubmissionFailed) {
...
}
},
child: Form(
key: _formKey,
child: Column(
children: [
// The reusable widget: Email input field.
BlocBuilder<LoginBloc, LoginState>(
builder:(context, state){
return emailInputField(context, state);
}
),
...
现在让我们看看 emailInputField 小部件
Widget emailInputField(BuildContext context, dynamic state) {
return TextFormField(
validator: (value) =>
state.isValidEmail ? null : 'Please input a valid email',
onChanged: (value) =>
// HERE - I want to decouple this widget from "LoginBloc".
context.read<LoginBloc>().add(LoginUsernameChanged(username: value)),
labelText: 'Email',
...
);
}
login_bloc.dart 登录块
class LoginBloc extends Bloc<BaseEvent, LoginState>{
LoginBloc() : super(LoginState());
@override
Stream<LoginState> mapEventToState(BaseEvent event) async*{
yield* event.handleEvent(state);
}
}
还有登录事件类,用于获得完整的图片login_event.dart
abstract class LoginEvent extends BaseEvent {
AuthenticationService authService = GetIt.I.get<AuthenticationService>();
}
// Event 1
class LoginUsernameChanged extends LoginEvent {
final String username;
LoginUsernameChanged({this.username});
@override
Stream<LoginState> handleEvent(BaseState state) async* {
// Dart style down-casting...
LoginState loginState = state;
yield loginState.copyWith(username: username);
}
}
base_event.dart
abstract class BaseEvent {
Stream<BaseState> handleEvent(BaseState state);
}
再一次,有没有办法将该视图与 BLoc 分离? 我希望我的问题在阅读后有意义。
附言
为了让事情变得更简单,我想到的一个想法是保留一个 Bloc 组件,该组件将处理一组相关的输入字段(密码/用户名),然后像我在 login 中所做的那样传递不同的状态.dart 调用 emailInput 小部件时的页面。
【问题讨论】:
标签: flutter dart bloc flutter-bloc