我正在使用StatefulWidget作为当前的仪表板页面。我在initState中调用后端,并在响应中创建下拉项。这部分工作正常!
我的问题是当我导航离开并返回页面时,出现以下错误:
There should be exactly one item with [DropdownButton]'s value: 5eb8e4670ae9b245c86b752b.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
'package:flutter/src/material/dropdown.dart':
Failed assertion: line 827 pos 15: 'items == null || items.isEmpty || value == null ||
items.where((DropdownMenuItem<T> item) {
return item.value == value;
}).length == 1'
调试之后,我看到我的下拉列表保留了上次的内容,因此当我返回页面并尝试从后端生成新的Item时,我不能,因为它已经在下拉列表中了。 / p>
我想在离开时破坏我的下拉菜单,但是我不知道该怎么做,我已经在使用dispose了,但是重置下拉菜单似乎还不够。
这是我此页面的代码,我将不胜感激,Flutter还是我的新手!谢谢!
信息中心:
class MyDashboard extends StatefulWidget {
MyDashboardState createState() => MyDashboardState();
}
class MyDashboardState extends State<MyDashboard> {
Future<List<dynamic>> loadAll() async {
DateTime now = new DateTime.now();
var model = Provider.of<DashboardModel>(context);
try {
final resp = await dio.post("/endpoint", data: {"date": date.millisecond});
model.addArray(resp.data);
return resp.data;
} catch (err) {
return Future.error(err);
}
}
@override
void initState() {
super.initState();
new Future.delayed(Duration.zero,() {
this.loadAll();
});
}
@override
Widget build(BuildContext context) {
var model = Provider.of<DashboardModel>(context);
print('LIST LENGTH: ' + model.getList().length.toString());
return Scaffold(
appBar: _MyAppBar(),
body: Center(
child: model.getListAsItems().length == 0 ? KidCreate() : KidSelect(),
),
)
);
}
}
孩子选择:
class KidSelect extends StatefulWidget {
_KidSelectState createState() => _KidSelectState();
}
String _mySelection;
class _KidSelectState extends State<KidSelect> {
List<DropdownMenuItem<String>> list;
@override
void dispose() {
// Clean up the controller when the widget is disposed.
list = new List();
_mySelection = null;
super.dispose();
}
Widget _buildSelect() {
var model = Provider.of<DashboardModel>(context);
_mySelection = _mySelection == null ? model.getList()[0].id.toString() : _mySelection;
list = model.getListAsItems();
return DropdownButton<String>(
hint: new Text("Select"),
value: _mySelection,
onChanged: (String newValue) {
setState(() {
_mySelection = newValue;
});
},
items: list,
);
}
@override
Widget build(BuildContext context) {
return Form(
child: Column(
children: <Widget>[
_buildSelect(),
]
)
);
}
}
答案 0 :(得分:0)
基于Vilsad P P的注释,使用本地状态而不是提供程序可以解决此问题。但是后来我意识到,由于实现了其他功能,我需要使用提供程序,因此我试图找出它无法正常工作的原因,我想我找到了它!
在导航时,模型提供者仪表板会将我的列表保存在内存中,因此当我向后导航时,它将第二次将值添加到列表中,并且在尝试下拉列表时会崩溃。为了防止这种情况,当我将我的api调用中的信息设置为模型时,而不是仅添加信息,而是在此之前重置了列表,因此列表就像新的一样!
我遇到的另一个问题是默认情况下下拉列表的选择,我试图将列表的第一项置于选中状态,但是在列表完全创建之前,我做得太早了,所以我更改了位置我将选择内容初始化为initState,并在api调用中添加了一个wait,以便它在分配我的第一个结果之前等待!
@override
void initState() {
super.initState();
new Future.delayed(Duration.zero,() async {
await this.loadAll();
var model = Provider.of<DashboardModel>(context);
_mySelection = model.getList().length > 0 ? model.getList()[0].id.toString() : null;
});
}
一切似乎都按照现在的方式运行!多亏了Vilsad,我才能够更好地理解颤振的原理!