我正在try 在空数组中添加项.我正在使用DIO包发送发帖请求.所有其他代码都工作正常.但在这里,我被这个问题难住了.我取了一个空array.然后,我try 使用setState函数将项添加到空列表中.每次按下 list ,我都会把它打印出来.但我得到的是空array.
实际上,我正在try 将产品添加到空数组中并发送POST请求.
以下是我的代码:
Consumer<ProductController>(
builder: ((context, value, child) {
// log('${value.products[0].results?.length.toString()}');
if (value.products.isNotEmpty) {
return Container(
height: maxHeight * 0.3,
child: ListView.builder(
itemCount: value.products[0].results!.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(value
.products[0].results![index].name!),
leading: IconButton(
icon: const Icon(Icons.add),
onPressed: () {
setState(() {
_lists.add(value.products[0]
.results![index].id);
_lists = productIds;
print("LISTS +>>>> $_lists");
});
},
),
trailing: const Icon(Icons.done),
),
);
},
));
} else {
return const CircularProgressIndicator();
}
}),
),
这是我的模特:
class DisplayModel {
String? status;
List<Results>? results;
DisplayModel({this.status, this.results});
DisplayModel.fromJson(Map<String, dynamic> json) {
status = json['status'];
if (json['results'] != null) {
results = <Results>[];
json['results'].forEach((v) {
results!.add(new Results.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status;
if (this.results != null) {
data['results'] = this.results!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Results {
int? id;
List<Products>? products;
List<Catalogs>? catalogs;
String? name;
Null? description;
String? category;
String? templateName;
Null? bannerText;
Results(
{this.id,
this.products,
this.catalogs,
this.name,
this.description,
this.category,
this.templateName,
this.bannerText});
Results.fromJson(Map<String, dynamic> json) {
id = json['id'];
if (json['products'] != null) {
products = <Products>[];
json['products'].forEach((v) {
products!.add(new Products.fromJson(v));
});
}
if (json['catalogs'] != null) {
catalogs = <Catalogs>[];
json['catalogs'].forEach((v) {
catalogs!.add(new Catalogs.fromJson(v));
});
}
name = json['name'];
description = json['description'];
category = json['category'];
templateName = json['template_name'];
bannerText = json['banner_text'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
if (this.products != null) {
data['products'] = this.products!.map((v) => v.toJson()).toList();
}
if (this.catalogs != null) {
data['catalogs'] = this.catalogs!.map((v) => v.toJson()).toList();
}
data['name'] = this.name;
data['description'] = this.description;
data['category'] = this.category;
data['template_name'] = this.templateName;
data['banner_text'] = this.bannerText;
return data;
}
}
class Products {
int? id;
String? name;
Null? unit;
String? price;
Null? salePrice;
String? image;
Null? category;
Null? badge;
Products(
{this.id,
this.name,
this.unit,
this.price,
this.salePrice,
this.image,
this.category,
this.badge});
Products.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
unit = json['unit'];
price = json['price'];
salePrice = json['sale_price'];
image = json['image'];
category = json['category'];
badge = json['badge'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['unit'] = this.unit;
data['price'] = this.price;
data['sale_price'] = this.salePrice;
data['image'] = this.image;
data['category'] = this.category;
data['badge'] = this.badge;
return data;
}
}
class Catalogs {
int? id;
Null? name;
Null? unit;
Null? price;
Null? salePrice;
String? image;
Null? video;
Null? badge;
Catalogs(
{this.id,
this.name,
this.unit,
this.price,
this.salePrice,
this.image,
this.video,
this.badge});
Catalogs.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
unit = json['unit'];
price = json['price'];
salePrice = json['sale_price'];
image = json['image'];
video = json['video'];
badge = json['badge'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['unit'] = this.unit;
data['price'] = this.price;
data['sale_price'] = this.salePrice;
data['image'] = this.image;
data['video'] = this.video;
data['badge'] = this.badge;
return data;
}
}
这是我的Post控制器:
Future<bool> addDisplay(String name, String category, String templateName,
File catalogsImage, File catalogsVideo, List<Products> productIds) async {
try {
// String fileName = catalogsImage.path.split('/').last;
var token = localStorage.getItem('access');
Dio dio = Dio();
FormData formData = FormData.fromMap({
"name": name,
"category": category,
"template_name": templateName,
"catalogs[0]image": await MultipartFile.fromFile(catalogsImage.path),
"catalogs[0]video": await MultipartFile.fromFile(catalogsVideo.path),
"products": productIds
});
var response = await dio.post(url,
data: formData,
options: Options(headers: {"Authorization": "Bearer $token"}));
if (response.statusCode == 200) {
notifyListeners();
return true;
} else {
return false;
}
} on DioError catch (e) {
print(e);
return false;
}
}
以下是前端的完整代码:
// ignore_for_file: sized_box_for_whitespace
import 'dart:developer';
import 'package:digitaldisplay/controllers/DisplayController.dart';
import 'package:digitaldisplay/controllers/ProductController.dart';
import 'package:digitaldisplay/models/DisplayModel.dart';
import 'package:digitaldisplay/views/widgets/Display.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:provider/provider.dart';
import 'dart:io';
class CreateDisplayMobile extends StatefulWidget {
const CreateDisplayMobile({super.key});
@override
State<CreateDisplayMobile> createState() => _CreateDisplayMobileState();
}
class _CreateDisplayMobileState extends State<CreateDisplayMobile> {
final ImagePicker picker = ImagePicker();
String _name = "";
String _category = "";
String _templateName = "";
File? catalogImage;
File? _catalogVideo;
List<Products> productIds = [];
final _form = GlobalKey<FormState>();
void _addDisplay() async {
var isValid = _form.currentState!.validate();
if (!isValid) {
return;
}
_form.currentState!.save();
bool create = await Provider.of<DisplayController>(context, listen: false)
.addDisplay(_name, _category, _templateName, catalogImage!,
_catalogVideo!, productIds);
if (create) {
print(create);
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Created"),
actions: [
ElevatedButton(
child: const Text("Return"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Failed to create display!"),
actions: [
ElevatedButton(
child: const Text("Return"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
}
}
@override
void initState() {
Provider.of<DisplayController>(context, listen: false).getDisplays();
Provider.of<ProductController>(context, listen: false).getProducts();
super.initState();
}
@override
Widget build(BuildContext context) {
List _lists = [];
final ButtonStyle buttonStyle1 = ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFc3232a),
shape: const StadiumBorder(),
minimumSize: const Size(100, 50),
);
final ButtonStyle buttonStyle2 = ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFc3232a),
shape: const StadiumBorder(),
minimumSize: const Size(100, 50),
);
final ButtonStyle buttonStyle3 = ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF111111),
shape: const StadiumBorder(),
minimumSize: const Size(100, 50),
);
double maxHeight = MediaQuery.of(context).size.height;
double maxWidth = MediaQuery.of(context).size.width;
return Scaffold(
// backgroundColor: Colors.deepPurple[200],
appBar: AppBar(
elevation: 0,
backgroundColor: const Color(0xFF111111),
title: const Text(
"Digital Display Generator",
textAlign: TextAlign.end,
),
),
body: SingleChildScrollView(
child: Column(children: [
const SizedBox(
height: 10,
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Consumer<DisplayController>(
builder: (context, value, child) {
log('${value.displays[0].results?.length.toString()}');
return Container(
height: maxHeight * 0.6,
width: maxWidth * 0.9,
child: GridView.count(
crossAxisSpacing: 5,
crossAxisCount: 1,
scrollDirection: Axis.horizontal,
children: List.generate(
value.displays.isNotEmpty
? value.displays[0].results!.length
: 0, (i) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: DisplayCard(
displayName:
value.displays[0].results![i].name!,
displayImage: value.displays[0].results![i]
.catalogs![0].image!,
id: value.displays[0].results![i].id!),
);
}),
),
);
},
),
],
),
Form(
key: _form,
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(10.0),
child: Text(
"Enter Name",
)),
Padding(
padding: EdgeInsets.all(10),
child: TextFormField(
validator: (v) {
if (v!.isEmpty) {
return "Please Enter a valid name";
} else {
return null;
}
},
onSaved: (value) {
_name = value as String;
},
autofocus: false,
style: const TextStyle(
fontSize: 15.0, color: Colors.black),
decoration: InputDecoration(
hintText: 'Name',
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 6.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Color.fromARGB(255, 73, 57, 55)),
borderRadius: BorderRadius.circular(0.0),
),
enabledBorder: UnderlineInputBorder(
borderSide: const BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(0.0),
),
),
),
),
const Padding(
padding: EdgeInsets.all(10.0),
child: Text(
"Enter Template Name",
)),
Padding(
padding: EdgeInsets.all(10),
child: TextFormField(
validator: (v) {
if (v!.isEmpty) {
return "Please Enter a valid name";
} else {
return null;
}
},
onSaved: (value) {
_templateName = value as String;
},
autofocus: false,
style: const TextStyle(
fontSize: 15.0, color: Colors.black),
decoration: InputDecoration(
hintText: 'Template Name',
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 6.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Color.fromARGB(255, 73, 57, 55)),
borderRadius: BorderRadius.circular(0.0),
),
enabledBorder: UnderlineInputBorder(
borderSide: const BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(0.0),
),
),
),
),
const Padding(
padding: EdgeInsets.all(10.0),
child: Text(
"Enter Category Name",
)),
Padding(
padding: EdgeInsets.all(10),
child: TextFormField(
validator: (v) {
if (v!.isEmpty) {
return "Please Enter a valid name";
} else {
return null;
}
},
onSaved: (value) {
_category = value as String;
},
autofocus: false,
style: const TextStyle(
fontSize: 15.0, color: Colors.black),
decoration: InputDecoration(
hintText: 'Category Name',
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 6.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(
color: Color.fromARGB(255, 73, 57, 55)),
borderRadius: BorderRadius.circular(0.0),
),
enabledBorder: UnderlineInputBorder(
borderSide: const BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(0.0),
),
),
),
),
const Padding(
padding: EdgeInsets.all(10.0),
child: Text(
"Select Product",
)),
Padding(
padding: const EdgeInsets.all(10.0),
child: Consumer<ProductController>(
builder: ((context, value, child) {
// log('${value.products[0].results?.length.toString()}');
if (value.products.isNotEmpty) {
return Container(
height: maxHeight * 0.3,
child: ListView.builder(
itemCount: value.products[0].results!.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(value
.products[0].results![index].name!),
leading: IconButton(
icon: const Icon(Icons.add),
onPressed: () {
setState(() {
_lists.add(value.products[0]
.results![index].id);
// _lists = productIds;
print("LISTS +>>>> $productIds");
});
},
),
trailing: const Icon(Icons.done),
),
);
},
));
} else {
return const CircularProgressIndicator();
}
}),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {
_getImageFromGallery();
// displayController.createDisplay(
// "name", "category", "templateName", "1");
},
child: Text("Add Image"),
style: buttonStyle1,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {
_getVideoFromGallery();
// displayController.createDisplay(
// "name", "category", "templateName", "1");
},
child: Text("Add Video"),
style: buttonStyle1,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: () {
_addDisplay();
},
child: Text("Add Display"),
style: buttonStyle2,
),
),
],
),
],
),
),
),
]),
));
}
void _getImageFromGallery() async {
XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
setState(() {
catalogImage = File(pickedFile.path);
});
}
}
void _getVideoFromGallery() async {
XFile? filepick = await picker.pickImage(source: ImageSource.gallery);
if (filepick != null) {
setState(() {
_catalogVideo = File(filepick.path);
});
}
}
}
因此,在添加到空列表后,我想保存它.我如何才能获得这一点?我有什么解决办法吗?