DropDownButton с Cubit

Для отображения списка категорий в раскрывающейся кнопке я использую Cubit, он работает. Моя проблема: можно ли использовать Cubit для отображения selectedCategory? Без использования setState? Теперь при выборе категории он не показывает мне selectedCategory. Локоть:

class CategoriesCubit extends Cubit<CategoriesState> {
  final DataBase dataBase;
  final Category category;

  CategoriesCubit(this.dataBase, this.category)
      : super(CategoriesInitial());
  StreamSubscription streamSubscription;

  Future getCategories() async {
    streamSubscription = dataBase.getCategories().listen((data) {
      emit(CategoriesLoaded(data));
    });
  }
  void setCategory(String selectedCategory) {
    category.categoryID = selectedCategory;
  }
}

Главный:

class Main extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => CategoriesCubit(DataBase(), Category()),
      child: DropDownButton(),
    );
  }
}

class DropDownButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    context.bloc<CategoriesCubit>().getCategories();
    final category = context.bloc<CategoriesCubit>().category;
    return Container(
      child: BlocBuilder<CategoriesCubit, CategoriesState>(
        builder: (context, state) {
            if (state is CategoriesLoaded) {
            return DropdownButton(
              value: category.categoryID,
              hint: Text('choose category'),
              items: state.categories
                  .map((category) => DropdownMenuItem(
                        child: Text(category.categoryName),
                        value: category.categoryID,
                      ))
                  .toList(),
              onChanged: (selectedCategory) {
                context.bloc<CategoriesCubit>().setCategory(selectedCategory);
                print(selectedCategory);
              },
            );
          }
        },
      ),
    );
  }
}

person Andrey Khan    schedule 10.09.2020    source источник


Ответы (1)


В вашей текущей реализации Cubit есть некоторые проблемы.

  1. Cubits должен быть неизменным. Вы не должны сохранять состояние в переменной внутри них, как вы сейчас делаете с переменной category.
  2. Вы получаете текущую выбранную категорию вне BlocBuilder, и она не будет обновляться при изменении состояния Cubit.
  3. Когда вы вызываете setCategory, состояние Cubit остается неизменным, поскольку вы ничего не излучаете.
  4. У вашего CategoriesCubit есть задача контролировать состояние загрузки категории. Лучше, если вы не добавите к нему еще одну задачу.

Я предлагаю сохранить selectedCategoryId как внутреннее состояние в вашем виджете, если вам не нужно делиться им между несколькими виджетами или сохранять его в его предках.

person Amir_P    schedule 18.09.2020