使用Riverpod实现日期筛选列表:解决选日期后全列表重复显示问题
解决日期筛选后列表重复显示问题
问题根源分析
- 服务层数据未正确重置:
pomvardimas作为服务类成员变量,仅在为空时赋值新数据,后续请求不会覆盖旧数据,导致新旧数据叠加。 - 视图层日期状态管理混乱:日期选择回调中临时设置日期后立即清空,且
getPompa方法忽略传入参数,使用已清空的本地变量,引发请求逻辑错误。 - 重复触发数据请求:
didChangeDependencies生命周期方法中调用getPompa(),每次组件依赖变化都会触发请求,导致重复加载。 - 状态冗余冲突:视图层同时维护本地日期变量与Riverpod的
timeProvider1,两者同步逻辑混乱,引发状态不一致。
修复步骤
1. 修复服务层数据更新逻辑
修改getAll方法,每次请求前清空旧数据,确保新数据完全替换旧数据:
Future<List<pompa.Pomvardimas>?> getAll({required WidgetRef ref}) async { String _query = NetworkRoutes.POMVARDIMAS.rawValue; final endDate = ref.watch(timeProvider1).endDate; final startDate = ref.watch(timeProvider1).startDate; if (endDate == DateTime(0) || startDate == DateTime(0)) { _query = NetworkRoutes.POMVARDIMAS.rawValue; } else { // 转换为后端兼容的日期格式,示例用ISO8601 final formattedStart = startDate.toIso8601String(); final formattedEnd = endDate.toIso8601String(); _query = "${NetworkRoutes.GETTWOBETWEENTIMEPOMPA.rawValue}?t1=$formattedStart&t2=$formattedEnd"; } final response = await manager.send<pompa.ResponsesModels, pompa.ResponsesModels>( _query, parseModel: pompa.ResponsesModels(), method: RequestType.GET, ); debugPrint("responseeeeeeeeeeee${response}"); // 强制清空旧数据,替换为新请求结果 pomvardimas.clear(); if (response != null && response.data?.data is List) { pomvardimas = List.from(response.data!.data!); } return pomvardimas; }
2. 简化视图层状态管理,移除冗余变量
删除本地日期变量,直接通过Riverpod管理状态:
class _ViewPageState extends ConsumerState with BaseViewModel { int? id; GlobalKey<ScaffoldState> scaffoldState1 = GlobalKey(); IPomvardimasService? _pomvardimasService; List<Pomvardimas>? _pomvardima; @override void initState() { super.initState(); _pomvardimasService = PomvardimasService(VexanaManager.instance.networkManager, scaffoldState1); } @override void didChangeDependencies() { super.didChangeDependencies(); // 仅首次加载时请求数据 if (_pomvardima == null) { getPompa(); } } Future getPompa() async { _pomvardima = await _pomvardimasService!.getAll(ref: ref); setState(() {}); } @override Widget build(BuildContext context) { int indexx = ref.watch(showHello); final user = ref.watch(userrProvider); id = user.id; return Scaffold( drawer: const DrawerPage(), appBar: AppBar( elevation: 0, bottom: PreferredSize( preferredSize: const Size.fromHeight(90.0), child: Column( children: [ indexx == 0 ? const HomeInput() : const SizedBox(), indexx == 2 ? Container( width: 300, height: 50, margin: EdgeInsets.only(bottom: 20), child: TextButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Colors.white), ), onPressed: () { final timeNotifier = ref.read(timeProvider1.notifier); showCustomDateRangePicker( context, dismissible: true, minimumDate: DateTime.now().subtract(const Duration(days: 360)), maximumDate: DateTime.now().add(const Duration(days: 360)), // 使用Riverpod中的日期作为初始值 endDate: ref.watch(timeProvider1).endDate == DateTime(0) ? null : ref.watch(timeProvider1).endDate, startDate: ref.watch(timeProvider1).startDate == DateTime(0) ? null : ref.watch(timeProvider1).startDate, backgroundColor: Colors.white, primaryColor: Colors.black, onApplyClick: (start, end) { timeNotifier.changeQuery1(start, end); getPompa(); }, onCancelClick: () { timeNotifier.changeQuery1(DateTime(0), DateTime(0)); getPompa(); }, ); }, child: Text("Tarih Aralığı Seciniz"), ), ) : SizedBox() ], ), ), backgroundColor: Colors.black, title: Text( " App", style: context.textTheme.headlineSmall?.copyWith( color: context.colors.onPrimary, ), ), centerTitle: true, actions: [ IconButton( onPressed: () { navigation.navigateToPageClear(path: NavigationConstants.LOGIN_VIEW); localeManager.deletedPref(PreferencesKeys.TOKEN); var token = LocaleManager.instance.getStringValue(PreferencesKeys.TOKEN); inspect(token); }, icon: const Icon( Icons.login_outlined, color: Colors.white, size: 30, ), ), ], ), body: Center( child: Expanded( child: Container( child: indexx == 0 ? CartView() : indexx == 1 ? MarView() : indexx == 2 ? PomView(data: _pomvardima) : const SizedBox(), ), ), ), ); } }
3. 优化TimeNotifier的方法命名与参数顺序
修正拼写错误,统一参数顺序:
class TimeNotifier1 extends ChangeNotifier { DateTime endDate = DateTime(0); DateTime startDate = DateTime(0); void changeQuery1(DateTime start, DateTime end) { startDate = start; endDate = end; notifyListeners(); } } final timeProvider1 = ChangeNotifierProvider<TimeNotifier1>((ref) { return TimeNotifier1(); });
4. 确保PomView正确接收最新数据
修改PomView,通过参数接收数据源:
class PomView extends StatelessWidget { final List<Pomvardimas>? data; const PomView({super.key, required this.data}); @override Widget build(BuildContext context) { return ListView.builder( itemCount: data?.length ?? 0, itemBuilder: (context, index) { final item = data![index]; return ListTile(title: Text(item.someProperty)); // 替换为实际属性 }, ); } }
关键注意事项
- 日期格式兼容性:直接转换
DateTime为字符串可能不符合后端要求,建议使用toIso8601String()或后端指定格式。 - 状态单一来源:统一通过Riverpod管理共享状态,避免本地变量与全局状态的同步冲突。
- 请求防抖:若日期选择操作频繁,可添加防抖逻辑,避免短时间内多次触发请求。
内容的提问来源于stack exchange,提问作者developer new
相关产品推荐
相关产品推荐

