如何通过Flutter Provider结合模型接收Node.js后端的sizesAndColors数据?
使用Flutter Provider结合数据模型接收Node.js后端的sizesAndColors数据
1. 定义对应的数据模型类
先根据后端返回的sizesAndColors结构,创建Dart数据模型,保证类型安全和JSON解析便捷:
class SizeColorModel { final String? color; final String? size; final int? quantity; final List<String>? images; SizeColorModel({ this.color, this.size, this.quantity, this.images, }); // 从JSON解析为模型对象 factory SizeColorModel.fromJson(Map<String, dynamic> json) { return SizeColorModel( color: json['color'], size: json['size'], quantity: json['quantity'], images: json['images'] != null ? List<String>.from(json['images']) : null, ); } // 可选:转成JSON用于回传后端 Map<String, dynamic> toJson() { return { 'color': color, 'size': size, 'quantity': quantity, 'images': images, }; } }
2. 创建Provider状态管理类
基于ChangeNotifier实现Provider,负责从后端请求数据、解析并维护状态:
import 'package:flutter/foundation.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; class ProductProvider extends ChangeNotifier { List<SizeColorModel> _sizesAndColors = []; bool _isLoading = false; String? _error; List<SizeColorModel> get sizesAndColors => _sizesAndColors; bool get isLoading => _isLoading; String? get error => _error; // 从后端获取并解析数据 Future<void> fetchSizesAndColors() async { _isLoading = true; _error = null; notifyListeners(); try { // 替换成你的Node.js后端接口地址 final response = await http.get(Uri.parse('https://your-api-url.com/sizes-colors')); if (response.statusCode == 200) { final List<dynamic> data = json.decode(response.body)['sizesAndColors']; _sizesAndColors = data.map((item) => SizeColorModel.fromJson(item)).toList(); } else { _error = '请求失败:${response.statusCode}'; } } catch (e) { _error = '网络错误:${e.toString()}'; } finally { _isLoading = false; notifyListeners(); } } }
3. 在项目中注册Provider
在main.dart里注册Provider,让整个应用可以访问状态:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; void main() { runApp( ChangeNotifierProvider( create: (context) => ProductProvider(), child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Provider Demo', home: const ProductDetailsScreen(), ); } }
4. 在UI中消费数据
用Consumer或Provider.of获取状态,展示数据:
class ProductDetailsScreen extends StatelessWidget { const ProductDetailsScreen({super.key}); @override Widget build(BuildContext context) { // 初始化时请求数据 WidgetsBinding.instance.addPostFrameCallback((_) { Provider.of<ProductProvider>(context, listen: false).fetchSizesAndColors(); }); return Scaffold( appBar: AppBar(title: const Text('商品规格颜色')), body: Consumer<ProductProvider>( builder: (context, provider, child) { if (provider.isLoading) { return const Center(child: CircularProgressIndicator()); } if (provider.error != null) { return Center(child: Text(provider.error!)); } return ListView.builder( itemCount: provider.sizesAndColors.length, itemBuilder: (context, index) { final item = provider.sizesAndColors[index]; return ListTile( title: Text('颜色:${item.color} | 尺码:${item.size}'), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('库存:${item.quantity}'), if (item.images != null && item.images!.isNotEmpty) Wrap( children: item.images!.map((img) { return Image.network(img, width: 50, height: 50, fit: BoxFit.cover); }).toList(), ), ], ), ); }, ); }, ), ); } }
关键注意点
- 确保后端返回的JSON字段名和模型类里的字段完全一致(比如后端是
color,模型里不能写成colour) - 处理JSON解析时的空值情况,避免崩溃
- 使用
listen: false在不需要监听状态变化的地方调用Provider的方法,提升性能
内容的提问来源于stack exchange,提问作者yasith
相关产品推荐
相关产品推荐

