Flutter:如何将Modal Route参数传递给POST请求?
Flutter问题:pushNamed传参后按钮点击报错"Undefined name 'index'"
通过pushNamed将selectedAthlete列表传递到SelectedAthletes页面后,ListView.builder中可通过index访问参数,但页面底部ElevatedButton的点击事件调用ApiService.insertPresences时,出现报错:
Undefined name 'index'.
Try correcting the name to one that is defined, or defining the name.
跳转页面代码
child: ElevatedButton( style: ElevatedButton.styleFrom( disabledBackgroundColor: Colors.grey), onPressed: (() async { Navigator.of(context).pushNamed( SelectedAthletes.routeName, arguments: selectedAthlete.toList()); })
接收参数页面代码
class SelectedAthletes extends StatefulWidget { const SelectedAthletes({Key? key}) : super(key: key); static const routeName = '/selectedAthletes'; @override State<SelectedAthletes> createState() => _SelectedAthletesState(); } class _SelectedAthletesState extends State<SelectedAthletes> { @override Widget build(BuildContext context) { final args = ModalRoute.of(context)!.settings.arguments as List<Athlete>; return Scaffold( backgroundColor: const Color(0Xfff7f7f5), body: Stack( children: [ SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ListView.builder( shrinkWrap: true, cacheExtent: 34, primary: true, physics: const ClampingScrollPhysics(), padding: const EdgeInsets.only( top: 10, bottom: 56, ), itemCount: args.length, itemBuilder: (BuildContext context, int index) { return ListTile( leading: const Icon(Icons.history_outlined, color: Colors.black, size: 25), title: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( 'ID: ${args[index].id}', style: const TextStyle( color: Colors.blue, fontSize: 14), ), const SizedBox( width: 5, ), Row( children: [ Flexible( child: Text( '${args[index].lastName} ${args[index].firstName}', style: const TextStyle( color: Colors.black, fontFamily: 'Cera', fontWeight: FontWeight.bold, fontSize: 18), ), ), ], ), const SizedBox( height: 5, ), Row( children: [ Text( '(${args[index].fatherName})', style: const TextStyle( color: Colors.black, fontFamily: 'Cera', fontSize: 14), ), const SizedBox( width: 20, ), Text( 'Π: ${args[index].currentMonthPresences}', style: const TextStyle( color: Colors.black, fontFamily: 'Cera', fontSize: 14), ), const SizedBox( width: 50, ), ], ), ], )); }, ) ], ), ), Align( alignment: Alignment.bottomCenter, child: Container( width: double.infinity, height: 60, child: ElevatedButton( style: ElevatedButton.styleFrom( disabledBackgroundColor: Colors.grey), onPressed: () async { await ApiService.insertPresences(args[index].id, args[index].firstName, args[index].lastName); }, child: const Center( child: Text( 'SEND', style: TextStyle( fontWeight: FontWeight.bold, color: Colors.white, fontSize: 18), ), ), ), ), ), ], )); } }
POST请求代码
static Future<Athlete> insertPresences( int athleteId, int departmentId, int teamId) async { try { final response = await http.post( Uri.parse( 'http://164.92.170.94:8080/nox/api/nox/api/insert-presences'), headers: { 'Authorization': 'Basic a2F4cmlzOjEyMzQ1', 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: jsonEncode(<String, int>{ "athleteId": athleteId, "departmentId": departmentId, "teamId": teamId, })); print('Response status: ${response.statusCode}'); print('Response body: ${response.body}'); if (response.statusCode == 201) { return Athlete.fromJson(jsonDecode(response.body)); } } catch (e) { logger.e(e.toString()); } return insertPresences(athleteId, departmentId, teamId); }
问题原因
index是ListView.builder的itemBuilder回调内的局部变量,仅在该回调的作用域中有效。按钮的点击事件处于这个作用域之外,因此无法访问index。另外,原代码中按钮调用API时传递的参数与insertPresences要求的参数不匹配,也会导致后续错误。
修复方案
1. 修正按钮点击事件,批量提交运动员数据
按钮的核心需求是提交所有选中的运动员数据,因此需要遍历整个args列表,对每个运动员调用API:
onPressed: () async { // 遍历所有选中的运动员,逐个提交 for (final athlete in args) { await ApiService.insertPresences(athlete.id, athlete.departmentId, athlete.teamId); } // 提交完成后返回上一页 if (mounted) { Navigator.pop(context); } },
2. 修正参数不匹配问题
原代码中传递的firstName、lastName与API要求的departmentId、teamId不符,必须替换为正确的参数,确保与insertPresences方法的参数列表一致。
3. 可选:优化为批量API调用(更高效)
如果后端支持批量提交,建议新增批量接口并修改前端代码,减少网络请求次数:
// 新增批量提交方法 static Future<void> insertBatchPresences(List<Athlete> athletes) async { try { final response = await http.post( Uri.parse('http://164.92.170.94:8080/nox/api/nox/api/insert-presences-batch'), headers: { 'Authorization': 'Basic a2F4cmlzOjEyMzQ1', 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: jsonEncode(athletes.map((athlete) => { "athleteId": athlete.id, "departmentId": athlete.departmentId, "teamId": athlete.teamId, }).toList()), ); print('Response status: ${response.statusCode}'); print('Response body: ${response.body}'); } catch (e) { logger.e(e.toString()); } }
然后按钮点击时调用批量方法:
onPressed: () async { await ApiService.insertBatchPresences(args); if (mounted) { Navigator.pop(context); } },
内容的提问来源于stack exchange,提问作者kate_3dev
相关产品推荐
相关产品推荐

