#flutter #dart #bloc
#flutter #dart #блок
Вопрос:
В приложении я использую Cubit. ItemData извлекается из firestore. Все работает, но после добавления элемента в список и обновления значения (имени) в firestore в списке остается старое значение. Как это решить?
class TestPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
BlocBuilder<ItemCubit, ItemState>(
cubit: ItemCubit(DataBase())..getItemData(item),
builder: (context, state) {
if (state is ItemData) {
return Column(
children: [
Text(state.item.name),
RaisedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TestPage1(
item: state.item,
)));
},
child: Text('showPage'),
),
RaisedButton(
onPressed: () {
context.bloc<TestCubit>().add(item);
},
)
],
);
}
return Container(
child: Text('error'),
);
},
)
],
),
);
}
}
для добавления элемента в список я использую другой
код cubit:
class AddCubit extends Cubit<AddState> {
AddCubit() : super(AddInitial());
List<Item> items = List<Item>();
void addItem(Item item) {
items.add(item);
emit(LoadList(items));
}
}
Это блок для получения списка элементов в TestPage1:
BlocBuilder<AddCubit, AddState>(builder: (context, state) {
if (state is LoadList) {
return Column(
children: state.items.toSet().map((item) {
return Card(
child: Text(item.name),
);
}).toList(),
);
}
})
код состояния:
class LoadList extends AddState {
final List<Item> items;
LoadList(this.items);
}
Ответ №1:
В flutter при сравнении двух объектов одного и того же класса у вас всегда будет равенство, даже если их значения различны. Если только вы не будете использовать метод равенства в своем классе.
Код класса с методом равенства
import 'package:equatable/equatable.dart';
class LoadList extends AddState {
final List<Item> items;
LoadList(this.items);
@override
List<Object> get props => [items];
}
Второе — это тот факт, что вы должны использовать copy with и не создавать новое состояние для нового значения. Это пригодится позже и уменьшит количество возможных ошибок в дальнейшем.
Весь код для класса состояния
import 'package:equatable/equatable.dart';
class LoadList extends AddState {
final List<Item> items;
LoadList(this.items);
LoadList copyWith({
List<Item> items,
}) {
return LoadList(
items: items?? this.items,
);
}
@override
List<Object> get props => [items];
}
И затем для вашей функции void вы должны использовать:
void addItem(Item item) {
items.add(item);
emit(state.copyWith(items: items);
}
Ответ №2:
просто к вашему сведению. Приведенный выше ответ не будет работать на 100%, если вы пытаетесь обновить свой виджет, потому что List.add немедленно обновит состояние (но не будет вызывать Bloc или Cubit из-за того, что Equatable сравнивает значения).
Поэтому, если вы хотите использовать List.add или List.remove, вам просто нужно где-то выполнить setState .