如何存储API生成的ID并通过GetByID从PostgreSQL获取名片数据?
解决方案
1. 完善DataDetails模型,加入唯一ID字段
你的数据库每条记录都有唯一ID,必须在数据模型中添加对应字段,确保API返回的JSON能正确解析这个ID:
class DataDetails { final String id; // 新增唯一ID字段 final String name; final String role; final String company; // 修正拼写错误:原comapny改为company final String address; final String email; final String phone; DataDetails({ required this.id, required this.name, required this.role, required this.company, required this.address, required this.email, required this.phone, }); // 从JSON解析时包含id字段 factory DataDetails.fromJson(Map<String, dynamic> json) { return DataDetails( id: json['id'].toString(), // 根据API返回的ID类型调整,可能是int或String name: json['name'], role: json['role'], company: json['company'], // 同步修正拼写 address: json['address'], email: json['email'], phone: json['phone'], ); } }
2. 列表页面添加点击事件,传递ID到详情页
在ListView的itemBuilder中,给名片容器添加点击事件,通过Navigator跳转到详情页并传递当前条目的ID:
// 修改列表项的Container,添加onTap交互 return GestureDetector( onTap: () { // 跳转到详情页面,传入当前条目的唯一ID Navigator.push( context, MaterialPageRoute( builder: (context) => ContactDetailsPage(contactId: dataDetaisl[index].id), ), ); }, child: Container( color: Color(0xFFCCF5FF), padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10), margin: EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Name : ${dataDetaisl[index].name}', style: TextStyle(fontSize: 16, color: Colors.black)), Text('Role : ${dataDetaisl[index].role}', style: TextStyle(fontSize: 16, color: Colors.black)), Text('Company : ${dataDetaisl[index].company}', // 修正拼写 style: TextStyle(fontSize: 16, color: Colors.black), maxLines: 1, ), Text('Address : ${dataDetaisl[index].address}', style: TextStyle(fontSize: 16, color: Colors.black), maxLines: 2, ), Text('Email : ${dataDetaisl[index].email}', style: TextStyle(fontSize: 16, color: Colors.black)), Text('Phone : ${dataDetaisl[index].phone}', style: TextStyle(fontSize: 16, color: Colors.black)), ], ), ), );
3. 实现通过ID获取单条数据的API方法
创建异步方法,接收ID参数,调用后端的GetByID接口(通常URL格式为/api/contacts/{id}):
Future<DataDetails?> getSingleContact(String contactId) async { final response = await http.get(Uri.parse('你的API地址/contacts/$contactId')); // 替换为实际接口URL if (response.statusCode == 200) { var data = jsonDecode(response.body.toString()); return DataDetails.fromJson(data); } else { // 请求失败时返回null,可根据需求添加错误提示逻辑 return null; } }
4. 详情页面实现单条数据展示
创建详情页面,接收传递的ID,用FutureBuilder调用API并渲染数据:
class ContactDetailsPage extends StatelessWidget { final String contactId; const ContactDetailsPage({super.key, required this.contactId}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('名片详情')), body: FutureBuilder<DataDetails?>( future: getSingleContact(contactId), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasData && snapshot.data != null) { final contact = snapshot.data!; return Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('姓名: ${contact.name}', style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 10), Text('职位: ${contact.role}', style: const TextStyle(fontSize: 16)), const SizedBox(height: 10), Text('公司: ${contact.company}', style: const TextStyle(fontSize: 16)), const SizedBox(height: 10), Text('地址: ${contact.address}', style: const TextStyle(fontSize: 16)), const SizedBox(height: 10), Text('邮箱: ${contact.email}', style: const TextStyle(fontSize: 16)), const SizedBox(height: 10), Text('电话: ${contact.phone}', style: const TextStyle(fontSize: 16)), ], ), ); } else { return const Center(child: Text('无法获取名片数据')); } }, ), ); } }
额外注意事项
- 修正原代码拼写错误:
comapny改为company,responce改为response,避免解析或展示异常 - 确保后端已实现
GetByID接口,能通过ID返回单条记录的JSON数据 - 可根据需求扩展错误处理,比如请求超时、接口报错时显示对应提示
内容的提问来源于stack exchange,提问作者Nihar
相关产品推荐
相关产品推荐

