gpt4 book ai didi

flutter - Dart/Flutter 中 BLoC 模式的最佳实践

转载 作者:行者123 更新时间:2023-12-03 03:30:15 25 4
gpt4 key购买 nike

在 Flutter 中使用 BLoC 模式时,在构建应用程序代码时,什么被认为是良好的编程习惯?
这是一个松散的问题,所以我将尝试举一个例子。假设您定义了一个 BLoC 类来处理特定 Widget 的验证,并且您希望通过在填充表单时发出各种事件来更新验证消息。
据我了解,您的 BLoC 可能如下所示:

import 'dart:async';
import 'package:myproject/bloc/base_bloc.dart';
import 'package:rxdart/rxdart.dart';

class SignUpBloc extends Bloc {
BehaviorSubject<String> _emailSubject;
BehaviorSubject<String> _nameSubject;
BehaviorSubject<String> _phoneSubject;
BehaviorSubject<String> _signUpSubject;

SignUpBloc() {
_emailSubject = new BehaviorSubject<String>.seeded('');
_nameSubject = new BehaviorSubject<String>.seeded('');
_phoneSubject = new BehaviorSubject<String>.seeded('');
_signUpSubject = new BehaviorSubject<String>.seeded('');
}

void nameChanged(String content) {
if (content?.isEmpty ?? true) {
_nameSubject.emit('Name is required for the sign-up process');
} else {
_nameSubject.emit('');
}
}

void emailChanged(String content) {
if (!_validEmail(content)) {
_emailSubject.emit(
'Please enter a valid email address (e.g. example@mydomain.com');
} else {
_emailSubject.emit('');
_email = content;
}
}

.
.
// Other functions are used to emit various messages here
.
.

Stream<String> get emailStream => _emailSubject.stream;
Stream<String> get nameStream => _nameSubject.stream;
Stream<String> get phoneStream => _phoneSubject.stream;
Stream<String> get signUpStream => _signUpSubject.stream;
}
...然后在您的 ui/view 中,您可能会执行以下操作:
StreamBuilder<String>(
stream: _bloc.emailStream,
builder: (context, snapshot) {
return Padding(
padding: EdgeInsets.only(top: 5.0),
child: Text(
snapshot?.data ?? '',
),
);
},
现在,对我来说,这段代码散发出一种糟糕的代码味道……特别是,继续定义 BehaviorSubjects 然后编写方法来启用对其相应流的访问似乎有点困惑。我在网上找到的所有示例都定义了一种与此非常相似的方法,虽然它确实允许将业务逻辑与 UI 分开,但感觉上有很多重复的工作来继续定义和公开主题。

最佳答案

虽然您的方法在某些情况下是合理的,但使用 Bloc像这样感觉多余。
一个 Bloc本身带有 2 个流(内置,抽象掉),一个用于事件,另一个用于状态。
按照您的示例,使用 Bloc 的更惯用的方法如下所示:
状态:

@immutable
abstract class FormState {
final String email;
final String name;
final String phone;
final String signUp;

final String emailError;
final String nameError;
final String phoneError;
final String signUpError;

FormState({
this.email = "",
this.name = "",
this.phone = "",
this.signUp = "",
this.emailError = "",
this.nameError = "",
this.phoneError = "",
this.signUpError = "",
});
}
事件:
@immutable
abstract class FormChangedEvent {
final String email;
final String name;
final String phone;
final String signUp;

FormChangedEvent({
this.email = "",
this.name = "",
this.phone = "",
this.signUp = "",
});
}
集团:
class FormBloc extends Bloc<FormChangedEvent, FormState> {
FormBloc() : super(FormState());

@override
Stream<FormState> mapEventToState(FormChangedEvent event) async* {
yield FormState(
email: event.email,
name: event.name,
phone: event.phone,
signUp: event.signUp,
emailError: (event.email == null || event.email.isEmpty)
? "This field should not be empty!"
: "",
nameError: (event.name == null || event.name.isEmpty)
? "This field should not be empty!"
: "",
phoneError: (event.phone == null || event.phone.isEmpty)
? "This field should not be empty!"
: "",
signUpError: (event.signUp == null || event.signUp.isEmpty)
? "This field should not be empty!"
: "",
);
}
}
通过该设置,您可以使用 BlocBuilder 收听您的集团的状态变化。在本例中,您将收到 FormState 的实例。其中包含整个表单的状态。
更进一步,您可以创建事件和状态子类并使用 is ( state is Loading , state is FormReady ) 根据您的需要呈现页面的不同状态。
我希望这有帮助。 :]

关于flutter - Dart/Flutter 中 BLoC 模式的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64462514/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com