Flutter中基于Provider按postId获取并展示帖子评论列表的实现
问题解决:Flutter中用Provider实现帖子列表到评论页的导航与数据展示
核心问题梳理
你的代码目前存在几个关键问题:
- 页面跳转传参类型不匹配:
HomePage跳转时传递的是PostModelClass对象,但CommentPage错误接收CommentModel类型,导致报错。 - 评论Provider未正确接收帖子ID:
GetCommentProvider中的userId未被赋值,无法根据帖子ID请求对应评论。 - 评论数据解析错误:
fetchComment方法错误尝试从jsonDecode['comments']取数据,但接口返回的直接是评论数组,无需提取comments字段。 - 评论页未主动触发数据请求:
CommentPage初始化时未调用Provider方法获取评论数据。
修正后的完整代码
1. 修正HomePage(跳转传参与页面名称)
class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override void initState() { final provider = Provider.of<GetPostProvider>(context, listen: false); provider.getMyData(); super.initState(); } @override Widget build(BuildContext context) { final provider = Provider.of<GetPostProvider>(context); return Scaffold( appBar: AppBar( title: const Text('帖子列表'), ), body: provider.isLoading ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: provider.postModelClass.length, itemBuilder: ((context, index) { final post = provider.postModelClass[index]; return Card( child: ListTile( onTap: () { Navigator.push(context, MaterialPageRoute(builder: (_) { // 传递PostModelClass对象获取帖子ID return CommentPage(post: post); })); }, leading: CircleAvatar( child: Text("${post.id}"), ), title: Text("${post.title}"), ), ); }))); } }
2. 修正CommentPage(接收正确参数并触发数据请求)
class CommentPage extends StatefulWidget { // 接收PostModelClass对象以获取帖子ID final PostModelClass post; const CommentPage({ Key? key, required this.post, }) : super(key: key); @override State<CommentPage> createState() => _CommentPageState(); } class _CommentPageState extends State<CommentPage> { @override void initState() { super.initState(); // 初始化时请求对应帖子的评论 final commentProvider = Provider.of<GetCommentProvider>(context, listen: false); commentProvider.getComment(widget.post.id!); } @override Widget build(BuildContext context) { final commentProvider = Provider.of<GetCommentProvider>(context); return Scaffold( appBar: AppBar(title: const Text('评论列表')), body: commentProvider.isLoading ? const Center(child: CircularProgressIndicator()) : ListView.builder( itemCount: commentProvider.comment.length, itemBuilder: ((context, index) { final comment = commentProvider.comment[index]; return ListTile( title: Text(comment.name ?? ''), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(comment.email ?? ''), const SizedBox(height: 4), Text(comment.body ?? ''), ], ), ); }))); } }
3. 修正GetCommentProvider(修复参数传递与数据解析)
class GetCommentProvider with ChangeNotifier { bool isLoading = false; List<CommentModel> comment = []; // 修改方法,接收帖子ID参数 getComment(int postId) async { isLoading = true; notifyListeners(); // 提前通知加载状态更新 comment = await getAllComment(postId); isLoading = false; notifyListeners(); } Future<List<CommentModel>> getAllComment(int postId) async { final response = await http.get( Uri.parse('https://jsonplaceholder.typicode.com/posts/$postId/comments')); List<CommentModel> mylist = []; try { if (response.statusCode == 200) { final jsonDecode = json.decode(response.body); for (var i in jsonDecode) { CommentModel _model = CommentModel.fromJson(i); mylist.add(_model); } return mylist; } else { return mylist; } } catch (e) { throw '加载评论失败: $e'; } } }
4. 模型类(无需修改)
PostModelClass和CommentModel保持你原有的代码即可。
关键优化点说明
- 类型匹配:确保页面间传递参数类型一致,CommentPage接收PostModelClass以获取帖子ID。
- 加载状态管理:在Provider中提前通知加载状态更新,避免页面空白。
- 数据解析修复:移除错误的
jsonDecode['comments']解析逻辑,直接处理接口返回的数组。 - 代码简化:移除HomePage中冗余的Consumer,直接使用Provider获取数据。
内容的提问来源于stack exchange,提问作者Dhiraj
相关产品推荐
相关产品推荐

