在 flutter_bloc 中改变 `currentState` 属性
mutate `currentState` property in flutter_bloc
我有一个 flutter 应用程序,其中我在 listView 小部件中按姓名和销售额显示员工列表。我有两个按钮供每个员工增加或减少他们的销售额。
我正在使用 flutter_bloc 进行状态管理。
这是员工 class。
class Employee extends Equatable {
int _id;
String _name;
double _salery;
Employee(this._id, this._name, this._salery);
// setters
set id(int id) {
this._id = id;
}
set name(String name) {
this._name = name;
}
set salery(double salery) {
this._salery = salery;
}
// getters
int get id => this._id;
String get name => this._name;
double get salery => this._salery;
}
这里是 class 作为事件。
@immutable
abstract class EmployeeEvent {
final int _index;
EmployeeEvent(this._index);
int get index => this._index;
}
class IncrementEvent extends EmployeeEvent {
IncrementEvent(int index) : super(index);
}
class DecrementEvent extends EmployeeEvent {
DecrementEvent(int index) : super(index);
}
这是处理状态的集团 class。
class EmployeeBloc extends Bloc<EmployeeEvent, List<Employee>> {
@override
List<Employee> get initialState => [
Employee(1, 'Employee One', 10000.0),
Employee(2, 'Employee Two', 10000.0),
Employee(3, 'Employee Three', 10000.0),
Employee(4, 'Employee Four', 10000.0),
Employee(5, 'Employee Five', 10000.0),
];
@override
Stream<List<Employee>> mapEventToState(EmployeeEvent event) async* {
// I have checked, the control reaches over here.
double currentSalery = currentState[event.index].salery;
if (event is IncrementEvent) {
// Increments the salery when user presses the increment button
currentState[event.index].salery = currentSalery + (currentSalery * 0.2);
} else if (event is DecrementEvent) {
currentState[event.index].salery = currentSalery - (currentSalery * 0.2);
}
print(currentState[event.index].salery); // even prints the incremented / decremented salery.
yield currentState;
}
}
屈服后,不会调用小部件 class 中的 BlocBuilder
。
如果我像这样更改方法,那么它会调用 BlocBuilder
,但我无法增加或减少特定索引处员工的销售额。
@override
Stream<List<Employee>> mapEventToState(EmployeeEvent event) async* {
if (event is IncrementEvent) {
yield currentState;
} else if (event is DecrementEvent) {
yield currentState;
}
}
如何增加或减少特定指数的特定员工的销售额?
您的主要问题是您没有任何 class 代表您所在的州。所以首先你应该创建所需的状态。您可以使用 bloc
website.
中提供的简单示例
为了全球理解:
BlocBuilder
将仅在这些情况下重建(equatable
):
- 新旧状态的实例运行时类型不同
- 新旧状态的实例是相同的实例类型它将通过调用
==
.[=38=深入比较先前状态和新状态的所有嵌套属性以了解发生了什么变化]
- 您还可以使用您在创建时提供的
conditional
属性 功能。
如果你想使用相同的实例,你可以扩展 Equatable
(来自 equatable
包 here) or do the same thing it's doing. (this 中 post 可以帮助你)。
对于你的案例,你可以这样做:
abstract class EmployeeState extends Equatable {
EmployeeState([List props = const []]) : super(props);
@override
String toString() => '$runtimeType{}';
}
class EmployeeLoaded extends EmployeeState{
EmployeeLoaded(this.employees):super([employees])
final List<Employee> employees;
}
如需进一步 info/help,您可以访问 bloc
gitter。
flutter bloc 要求您生成状态的新实例,而不是修改 currentState。
所以我在下面做了如下改动类。
class Employee extends Equatable {
int id;
String name;
double salery;
Employee(this.id, this.name, this.salery) : super([id, name, salery]);
Employee copyWith({
String name,
double salery,
}) {
return Employee(this.id, name ?? this.name, salery ?? this.salery);
}
@override
String toString() {
return 'Employee { id: $id, name: $name, salery: $salery }';
}
}
修改了 mapEventToState 方法并添加了一个辅助方法来更新列表属性。
@override
Stream<List<Employee>> mapEventToState(EmployeeEvent event) async* {
yield this.updateList(event);
}
Stream<EmployeeState> updateList(EmployeeEvent event) async* {
final id = (currentState as EmployeeLoaded).employee[event.index].id;
List<Employee> employeeUpdate =
(currentState as EmployeeLoaded).employee.map((employee) {
if (employee.id == id) {
return employee.copyWith(
salery: (event is IncrementEvent)
? employee.salery + 200
: employee.salery - 200);
}
return employee;
}).toList();
print((currentState as EmployeeLoaded).employee == employeeUpdate);
print(currentState == EmployeeLoaded(employeeUpdate));
yield EmployeeLoaded(employeeUpdate);
}
我有一个 flutter 应用程序,其中我在 listView 小部件中按姓名和销售额显示员工列表。我有两个按钮供每个员工增加或减少他们的销售额。
我正在使用 flutter_bloc 进行状态管理。
这是员工 class。
class Employee extends Equatable {
int _id;
String _name;
double _salery;
Employee(this._id, this._name, this._salery);
// setters
set id(int id) {
this._id = id;
}
set name(String name) {
this._name = name;
}
set salery(double salery) {
this._salery = salery;
}
// getters
int get id => this._id;
String get name => this._name;
double get salery => this._salery;
}
这里是 class 作为事件。
@immutable
abstract class EmployeeEvent {
final int _index;
EmployeeEvent(this._index);
int get index => this._index;
}
class IncrementEvent extends EmployeeEvent {
IncrementEvent(int index) : super(index);
}
class DecrementEvent extends EmployeeEvent {
DecrementEvent(int index) : super(index);
}
这是处理状态的集团 class。
class EmployeeBloc extends Bloc<EmployeeEvent, List<Employee>> {
@override
List<Employee> get initialState => [
Employee(1, 'Employee One', 10000.0),
Employee(2, 'Employee Two', 10000.0),
Employee(3, 'Employee Three', 10000.0),
Employee(4, 'Employee Four', 10000.0),
Employee(5, 'Employee Five', 10000.0),
];
@override
Stream<List<Employee>> mapEventToState(EmployeeEvent event) async* {
// I have checked, the control reaches over here.
double currentSalery = currentState[event.index].salery;
if (event is IncrementEvent) {
// Increments the salery when user presses the increment button
currentState[event.index].salery = currentSalery + (currentSalery * 0.2);
} else if (event is DecrementEvent) {
currentState[event.index].salery = currentSalery - (currentSalery * 0.2);
}
print(currentState[event.index].salery); // even prints the incremented / decremented salery.
yield currentState;
}
}
屈服后,不会调用小部件 class 中的 BlocBuilder
。
如果我像这样更改方法,那么它会调用 BlocBuilder
,但我无法增加或减少特定索引处员工的销售额。
@override
Stream<List<Employee>> mapEventToState(EmployeeEvent event) async* {
if (event is IncrementEvent) {
yield currentState;
} else if (event is DecrementEvent) {
yield currentState;
}
}
如何增加或减少特定指数的特定员工的销售额?
您的主要问题是您没有任何 class 代表您所在的州。所以首先你应该创建所需的状态。您可以使用 bloc
website.
为了全球理解:
BlocBuilder
将仅在这些情况下重建(equatable
):
- 新旧状态的实例运行时类型不同
- 新旧状态的实例是相同的实例类型它将通过调用
==
.[=38=深入比较先前状态和新状态的所有嵌套属性以了解发生了什么变化] - 您还可以使用您在创建时提供的
conditional
属性 功能。
如果你想使用相同的实例,你可以扩展 Equatable
(来自 equatable
包 here) or do the same thing it's doing. (this 中 post 可以帮助你)。
对于你的案例,你可以这样做:
abstract class EmployeeState extends Equatable {
EmployeeState([List props = const []]) : super(props);
@override
String toString() => '$runtimeType{}';
}
class EmployeeLoaded extends EmployeeState{
EmployeeLoaded(this.employees):super([employees])
final List<Employee> employees;
}
如需进一步 info/help,您可以访问 bloc
gitter。
flutter bloc 要求您生成状态的新实例,而不是修改 currentState。
所以我在下面做了如下改动类。
class Employee extends Equatable {
int id;
String name;
double salery;
Employee(this.id, this.name, this.salery) : super([id, name, salery]);
Employee copyWith({
String name,
double salery,
}) {
return Employee(this.id, name ?? this.name, salery ?? this.salery);
}
@override
String toString() {
return 'Employee { id: $id, name: $name, salery: $salery }';
}
}
修改了 mapEventToState 方法并添加了一个辅助方法来更新列表属性。
@override
Stream<List<Employee>> mapEventToState(EmployeeEvent event) async* {
yield this.updateList(event);
}
Stream<EmployeeState> updateList(EmployeeEvent event) async* {
final id = (currentState as EmployeeLoaded).employee[event.index].id;
List<Employee> employeeUpdate =
(currentState as EmployeeLoaded).employee.map((employee) {
if (employee.id == id) {
return employee.copyWith(
salery: (event is IncrementEvent)
? employee.salery + 200
: employee.salery - 200);
}
return employee;
}).toList();
print((currentState as EmployeeLoaded).employee == employeeUpdate);
print(currentState == EmployeeLoaded(employeeUpdate));
yield EmployeeLoaded(employeeUpdate);
}