javascript - Flutter Firestore 集合相关的下拉菜单
问题描述
我正在尝试使用flutter和firestore作为后端来实现级联下拉菜单。到目前为止,这是我的代码,它通过独立加载所有类别和子类别来工作。
class AddProductScreen extends StatefulWidget {
final ProductData? data;
AddProductScreen({this.data});
@override
AddProductScreenState createState() => AddProductScreenState();
}
class AddProductScreenState extends State<AddProductScreen> {
AsyncMemoizer categoryMemoizer = AsyncMemoizer<List<CategoryData>>();
AsyncMemoizer subCategoryMemoizer = AsyncMemoizer<List<SubCategoryData>>();
CategoryData? selectedCategory;
SubCategoryData? selectedSubCategory;
// CategoryData selectedSubCategory;
List<CategoryData> categories = [];
List<SubCategoryData> subCategories = [];
@override
void initState() {
super.initState();
init();
}
Future<void> init() async {
categories = await categoryService.categoriesFuture();
subCategories = await subCategoryService.categoriesFuture();
setState(() {});
}
@override
void setState(fn) {
if (mounted) super.setState(fn);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: white,
appBar: AppBar(
backgroundColor: white,
elevation: 0.0,
title: Text('Title'),
actions: [
isUpdate
? IconButton(
icon: Icon(Icons.delete_forever, color: black),
onPressed: () {
_showMyDialog();
},
).paddingOnly(right: 8)
: SizedBox(),
],
),
body: SingleChildScrollView(
child: Form(
key: formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (categories.isNotEmpty)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Select Category', style: boldTextStyle(size: 18)),
8.height,
Container(
width: context.width() * 0.45,
decoration: BoxDecoration(
borderRadius: radius(), color: Colors.grey.shade200),
padding:
EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: DropdownButton(
underline: Offstage(),
items: categories.map((e) {
return DropdownMenuItem(
child: Text(e.name.validate()), value: e);
}).toList(),
isExpanded: true,
value: selectedCategory,
onChanged: (dynamic c) {
selectedCategory = c;
setState(() {
});
},
),
),
],
),
if (subCategories.isNotEmpty)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Select Sub Category', style: boldTextStyle(size: 18)),
8.height,
Container(
width: context.width() * 0.45,
decoration: BoxDecoration(
borderRadius: radius(), color: Colors.grey.shade200),
padding:
EdgeInsets.symmetric(horizontal: 16, vertical: 4),
child: DropdownButton(
underline: Offstage(),
items: subCategories.map((e) {
return DropdownMenuItem(
child: Text(e.name.validate()), value: e);
}).toList(),
isExpanded: true,
value: selectedSubCategory,
onChanged: (dynamic c) {
selectedSubCategory = c;
setState(() {});
},
),
),
],
),
],
).paddingAll(16),
),
),
).cornerRadiusWithClipRRect(16);
}
}
这是firestore调用
Future<List<SubCategoryData>> categoriesFuture() async {
return await ref!.get().then((x) => x.docs
.map((y) => SubCategoryData.fromJson(y.data() as Map<String, dynamic>))
.toList());
}
Future<List<SubCategoryData>> categoriesFutureById(String? doc) async {
DocumentReference categoryRef = db.doc('categories/' + doc.toString());
return await ref!
.where(SubCategoryKeys.categoryRef, isEqualTo: categoryRef)
.get()
.then((x) => x.docs
.map((y) =>
SubCategoryData.fromJson(y.data() as Map<String, dynamic>))
.toList());
}
调用第一个down的onchanged方法怎么办?
解决方案
我终于通过修改第一个下拉的 onChanged 方法来解决它,如下所示。
onChanged: (dynamic c) {
selectedCategory = c;
if (selectedCategory!.id != null) {
loadSubcategories(selectedCategory!.id);
}
setState(() {});
},
Future<void> loadSubcategories(String? docId) async {
DocumentReference categoryRef = db.doc('categories/' + docId.toString());
subCategoryService.categoriesFutureById(categoryRef).then((value) {
// isLoading = false;
log(value);
subCategories.clear();
subCategories.addAll(value);
selectedSubCategory = subCategories.first;
setState(() {});
}).catchError((e) {
//isLoading = false;
setState(() {});
toast(e.toString());
});
}
推荐阅读
- python - Get_Absolute_URL 从 Django 中的另一个模型中通过多对多字段反转 Slug
- r - 函数中 enquo() 和 toString() 的区别
- c# - 如何为 Xamarin 应用程序或 Blazor 应用程序设置 C# 共享逻辑?
- javascript - 我正在尝试使用 google drive api 上传图片,但我收到了一些错误响应
- api - REST API 如何在请求中分离授权类型密码和 client_credentials?
- vim - 为什么 ctags 排除 (--exclude) 对我不起作用?
- oracle - ORACLE PL/SQL 使用单个 insert 语句插入多个对象
- javascript - 使用 JavaScript 中的 HTML 代码调用匿名函数来更改鼠标悬停时的 div 背景颜色
- flutter - 在 IOS 14 上构建时找不到 CFBundleVersion
- list - 删除列表的中间元素