改变flutter_bloc中的`currentState`属性
Posted
技术标签:
【中文标题】改变flutter_bloc中的`currentState`属性【英文标题】:mutate `currentState` property in flutter_bloc 【发布时间】:2019-11-22 02:58:24 【问题描述】:我有一个颤动的应用程序,我在 listView 小部件中按姓名和销售人员显示员工列表。我为每个员工设置了两个按钮来增加或减少他们的销售额。
我正在使用flutter_bloc 进行状态管理。
这里是 Employee 类。
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;
这是作为事件的类。
@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);
这是处理状态的 bloc 类。
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;
屈服后,不会调用小部件类中的BlocBuilder
。
如果我像这样更改方法,那么它会调用BlocBuilder
,但我不能在特定索引处增加或减少员工的销售额。
@override
Stream<List<Employee>> mapEventToState(EmployeeEvent event) async*
if (event is IncrementEvent)
yield currentState;
else if (event is DecrementEvent)
yield currentState;
我如何在特定指数增加或减少特定员工的销售额?
【问题讨论】:
【参考方案1】:您的主要问题是您没有任何代表您的状态的类。所以首先你应该创建需要的状态。您可以使用bloc
website中提供的简单示例。
为了全球理解:
BlocBuilder
将仅在这些情况下重建(使用 equatable
):
==
深入比较前一个和新状态的所有嵌套属性以了解发生了什么变化。
您还可以使用您在创建时提供的conditional
属性函数。
如果你想使用相同的实例,你可以扩展Equatable
(来自equatable
包here)或做同样的事情。 (thismedium 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;
如需更多信息/帮助,您可以拨打bloc
gitter。
【讨论】:
【参考方案2】: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_bloc中的`currentState`属性的主要内容,如果未能解决你的问题,请参考以下文章
flutter_bloc :使 initialState 方法异步