//File: email_sign_in_model.dart
class EmailSignInModel {
EmailSignInModel({
this.email='',
this.formType=EmailSignInFormType.signIn,
this.isLoading=false,
this.password='',
this.submitted=false,
});
final String email;
final String password;
final EmailSignInFormType formType;
final bool isLoading;
final bool submitted;
EmailSignInModel copyWith({
String email,
String password,
EmailSignInFormType formType,
bool isLoading,
bool submitted,
}) {
return EmailSignInModel(
email: email ?? this.email,
password: password?? this.password,
formType: formType?? this.formType,
isLoading: isLoading?? this.isLoading,
submitted: submitted?? this.submitted
);
}
}
//File: email_sign_in_bloc.dart
import 'dart:async';
import 'package:timetrackerapp/app/sign_in/email_sign_in_model.dart';
class EmailSignInBloc {
final StreamController<EmailSignInModel> _modelController = StreamController<EmailSignInModel>();
Stream<EmailSignInModel> get modelStream => _modelController.stream;
EmailSignInModel _model = EmailSignInModel();
void dispose() {
_modelController.close();
}
void updateWith({
String email,
String password,
EmailSignInFormType formType,
bool isLoading,
bool submitted
}) {
//update model
_model = _model.copyWith(
email:email,
password: password,
formType: formType,
isLoading: isLoading,
submitted: submitted
);
//add updated model _tomodelController
_modelController.add(_model);
}
}
嗨,我是 Flutter 和 dart 的新手,正在尝试学习 Flutter 中的 bloc,我正在尝试使用 BLOC 并且还创建了一个模型类。我的问题是 copyWith({}) 是什么以及它对 email_sign_in_model 和 email_sign_in_bloc 做了什么? updateWith 在代码中做了什么?非常感谢!
假设您有一个对象想要更改其中的某些属性。一种方法是一次更改每个属性,例如
object.prop1 = x
object.prop2 = y
等等。如果您要更改的属性较多,这将变得很麻烦。那么copyWith
方法就派上用场了。此方法获取所有属性(需要更改)及其相应的值,并返回具有您所需属性的新对象。
updateWith
方法通过再次调用 copyWith
方法执行相同的操作,最后将返回的对象推送到流中。
假设你有一个类似的课程:
class PostSuccess {
final List<Post> posts;
final bool hasReachedMax;
const PostSuccess({this.posts, this.hasReachedMax});
functionOne(){
///Body here
}
}
假设您想随时更改类的某些属性,您可以像这样声明 copyWith 方法:
PostSuccess copyWith({
List<Post>? posts,
bool? hasReachedMax,
}) {
return PostSuccess(
posts: posts ?? this.posts,
hasReachedMax: hasReachedMax ?? this.hasReachedMax,
);
}
如您所见,在返回部分,您可以根据情况更改属性值并返回对象。
copyWith
是一个简单的方法,可以帮助改变对象。尽管我们也可以使用简单的设置器来做到这一点。我会详细说明答案,因为它包含 bloc
标签。
块和模型
在使用 bloc 模式时建议使用不可变模型,因为 bloc 模式期望用户使用支持值比较的类或模型。为了支持值比较,建议该类应该是不可变的。 (高效构建需要不可变对象,您可以在这里了解更多信息)。
示例
模型.dart
class Model {
String name;
String value;
Model({required this.name, required this.value});
}
这里的对象不支持值比较。因此可以使用:
void main(){
final model = Model(name: 'my model', value: '1.9');
model.value = '2.0';
}
但是当涉及到不可变的模型时。
@immutable
class Model {
final String name;
final String value;
const Model({required this.name, required this.value});
Model copyWith({
String? name,
String? value,
}) {
return Model(
name: name ?? this.name,
value: value ?? this.value,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is Model &&
other.name == name &&
other.value == value;
}
@override
int get hashCode => name.hashCode ^ value.hashCode;
}
现在您将无法使用 setter,因为它们是最终字段。所以你必须使用copyWith方法。
void main(){
final model = Model(name: 'my model', value: '1.9');
model.copyWith(value: '2.0');
}
现在在上面对象的 copyWith 中,您不能将值设为可为空。为此,我们在 copyWith 方法中使用功能参数。
@immutable
class Model {
final String name;
final String? value;
const Model({required this.name, required this.value});
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is Model && other.name == name && other.value == value;
}
@override
int get hashCode => name.hashCode ^ value.hashCode;
Model copyWith({
String? name,
String? Function()? value,
}) {
return Model(
name: name ?? this.name,
value: value != null ? value() : this.value,
);
}
}
现在您也可以传递空值。
void main(){
final model = Model(name: 'my model', value: '1.9');
model.copyWith(value: () => null);
}
希望这能帮助您更好地使用 bloc。