StateNotifierProvider:是否可以使用单个 StateNotifierProvider

时间:2021-07-22 17:15:00

标签: flutter riverpod

class SearchFilterModel {
  bool searchByDistance;
  bool filterByStatusOpen;
  String searchText;

  ...
}

class SearchFilterModelNotifier extends StateNotifier<SearchFilterModel> {
  SearchFilterModelNotifier() 
    : super(SearchFilterModel(
        searchByDistance: true,
        filterByStatusOpen: false,
        searchText: ''));

  void updateSearchByDistance(bool searchByDistance) {
    state.searchByDistance = searchByDistance;
  }

  void updateFilterByStatusOpen(bool filterByStatusOpen) {
    state.filterByStatusOpen = filterByStatusOpen;
  }

  void updateSearchText(String searchText) {
    state.searchText = searchText;
  }
}

final searchFilterModelNotifierProvider = StateNotifierProvider<SearchFilterModelNotifier, SearchFilterModel>((ref) => SearchFilterModelNotifier());

class SearchForm extends ConsumerWidget {
  @override
  Widget build(context, watch) {
    final searchFilterModelNotifier = watch(searchFilterModelNotifierProvider.notifier);
    final searchFilterModel = watch(searchFilterModelNotifierProvider);

    return Form(
      child: Column(
        children: [
          SwitchListTile(
            value: searchFilterModel.searchByDistance,
            onChanged: (bool value) => searchFilterModelNotifier.updateSearchByDistance(value),
            title: Text('Search by distance?')),
          SwitchListTile(
            value: searchFilterModel.filterByStatusOpen,
            onChanged: (bool value) => searchFilterModelNotifier.updateFilterByStatusOpen(value),
            title: Text('Filter by open status?')),
          // not even sure how to do the text one if using a TextFormField
          ]
        )
      );
    }
}

好的,我的项目结构如此,开关的值没有按预期运行,它们的值根本没有更新,我相信只是小部件没有重建。我能够为每个表单字段使用不同的状态提供程序来完成这项工作,但是当我有很多表单字段时,能够拥有一个代表整个表单的单个 StateNotifierProvider 会更好。这是不可能的事情吗?

1 个答案:

答案 0 :(得分:0)

答案是将 StateNotifier 方法更新为类似

void updateSearchByDistance(bool searchByDistance) {
  state = SearchFilterModel(... searchByDistance: searchByDistance);
}