我有一个屏幕,必须重新加载(从API获取新的数据),每次用户导航到(即使当用户按下返回按钮)。
我正在使用riverpod
中的AsyncValue
和GoRouter
这是屏幕代码
class BatchScreen extends ConsumerWidget {
static const String screenPath = "/BatchScreen";
const BatchScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final AsyncValue<BatchModel?> btachController =
ref.watch(batchControllerProvider);
final AuthRepository authRepository = ref.watch(authRepositoryProvider);
ref.listen<AsyncValue<void>>(
batchControllerProvider,
(_, state) => state.whenOrNull(
error: (error, stackTrace) {
// show snackbar if an error occurred
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
error.toString(),
),
),
);
},
),
);
Size size = MediaQuery.of(context).size;
bool isBegin = false;
return SafeArea(
child: Stack(
children: [
Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(250),
child: CustomeAppBar(
dynamicWidget: Expanded(
flex: 6,
child: UserInfo(
userId: authRepository.userModel.id,
fullName: authRepository.userModel.name,
warehouse: 'casablanca',
),
),
),
),
body: Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(16),
child: Column(
mainAxisAlignment: (isBegin)
? MainAxisAlignment.spaceAround
: MainAxisAlignment.center,
children: [
Column(
children: [
(isBegin)
? CustomButton(
ontap: () {
GoRouter.of(context).pushNamed(
APP_PAGE.palettQrCode.toName,
);
},
width: size.width / 1.2,
height: size.height / 12,
text: context.loc.continuee,
colorText: Colors.white,
backgroundColor: colorPrimary,
)
: StartButton(
ontap: () {
bool test = false;
QuickAlert.show(
context: context,
type: QuickAlertType.confirm,
text: 'Do you want to logout',
confirmBtnText: 'Yes',
cancelBtnText: 'No',
confirmBtnColor: Colors.green,
onConfirmBtnTap: () async {
// on error
if (test) {
await QuickAlert.show(
context: context,
type: QuickAlertType.error,
text: 'Please input something',
);
return;
}
Navigator.pop(context);
QuickAlert.show(
context: context,
type: QuickAlertType.loading,
title: 'Loading',
text: 'Fetching your data',
barrierDismissible: false,
);
await Future.delayed(
Duration(milliseconds: 3000),
() async {
if (context.mounted) {
Navigator.pop(context);
GoRouter.of(context).pushNamed(
APP_PAGE.palett.toName,
);
}
},
);
},
);
},
),
const SizedBox(height: 20),
if (isBegin)
CustomButton(
ontap: () {
GoRouter.of(context).pop();
},
width: size.width / 1.2,
height: size.height / 12,
text: context.loc.close,
colorText: Colors.white,
backgroundColor: Colors.black,
borderColor: Colors.black,
),
],
),
if (isBegin)
CustomButton(
ontap: () {
GoRouter.of(context).pop();
},
width: size.width / 1.2,
height: size.height / 12,
text: "Abondon",
colorText: Colors.red,
backgroundColor: Colors.white,
borderColor: Colors.red,
),
],
),
),
),
btachController.when(
data: (data) {
logDebug(data);
return const Positioned(
left: 23,
top: 200,
child: BatchProduct(
countProduct: 29,
),
);
},
error: (error, stackTrace) {
return Positioned(
left: 23,
top: 200,
child: Container(
height: 100,
width: size.width / 1.12,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.4),
spreadRadius: 4,
blurRadius: 5,
),
],
),
child: const Center(
child: Text(
'Uh oh. Something went wrong!',
style: TextStyle(
fontSize: 20,
color: Colors.black,
decoration: TextDecoration.none,
fontFamily: 'almarai',
),
),
),
),
);
},
loading: () {
return Positioned(
left: 23,
top: 200,
child: Container(
height: 100,
width: size.width / 1.12,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.4),
spreadRadius: 4,
blurRadius: 5,
),
],
),
child: const Center(
child: CircularProgressIndicator(),
),
),
);
},
),
],
),
);
}
}
我在用一个控制器来处理所有的功能性工作
class BatchController extends StateNotifier<AsyncValue<BatchModel?>> {
final BatchRepository batchRepository;
BatchController({required this.batchRepository})
: super(const AsyncValue.data(null)) {
getBatch();
}
Future<void> getBatch() async {
try {
state = const AsyncValue.loading();
await Future.delayed(Duration(milliseconds: 2000));
final List<BatchModel> bacth = await batchRepository.getBatch();
state = AsyncValue.data(bacth.first);
logDebug('hello');
logDebug(state);
} on DioError catch (e) {
state = AsyncValue.error(
"Uh oh. Something went wrong!",
StackTrace.current,
);
}
}
}
final batchControllerProvider =
StateNotifierProvider<BatchController, AsyncValue<BatchModel?>>(
(ref) {
final batchRepository = ref.read(batchRepositoryProvider);
return BatchController(batchRepository: batchRepository);
},
);
问题是当用户第一次在屏幕上着陆时,API调用并获得数据,但是如果用户导航回来或转到新屏幕并回到该屏幕,则用户获得相同的先前数据(而不调用API)。
关键是我想在用户每次登陆这个屏幕时调用一个API。
1条答案
按热度按时间uinbv5nw1#
GoRouter
是这样的:继承对象> ChangeNotifier > GoRouter
这意味着可以通过
addListener
方法添加所需的操作(当BatchController
类不再使用时,可以通过ref.onDispose
删除它)。要点是获取
GoRouter
的示例,并在类BatchController
的初始化中添加一个方法,其中将调用based on the route来更新状态(/data)。有关更多信息,您可以转到this repository,它为您提供了Riverpod + GoRouter捆绑包的新外观。