Flutter Firestore 集合相关的下拉菜单
Posted
技术标签:
【中文标题】Flutter Firestore 集合相关的下拉菜单【英文标题】:Flutter Firestore Collection Dependent Drop Down Menus 【发布时间】:2021-12-21 02:45:08 【问题描述】:我正在尝试使用 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方法被调用怎么办?
【问题讨论】:
【参考方案1】:我终于通过修改first drop down的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());
);
【讨论】:
以上是关于Flutter Firestore 集合相关的下拉菜单的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 中监听 Firestore 集合及其子集合
Flutter 使用 Stream 检索 Firestore 集合
在 Firestore 中删除集合 - Flutter/Android