在DropdownButton中选择项目会导致Flutter引发错误

时间:2019-01-02 16:45:03

标签: dart flutter

我目前正在尝试从REST API检索数据(标签),并使用该数据填充一个可以成功完成的下拉菜单,但是选择该项目后,出现以下错误,根据{{3} }表示“所选值不是值列表的成员”:

  

项== null ||值== null || items.where(((DropdownMenuItem item)=> item.value == value).length == 1':不正确。

这是在下拉菜单显示我选择的项目之后发生的。但是,这不是应该发生的错误,因为我已经完成了必要的日志记录,以检查数据是否确实分配给了相关列表。谁能帮我解决这个问题?我已经将其隔离到源自DropdownButton的setState()中的onChanged方法的原因,但是似乎无法理解为什么这会引起问题。任何帮助将不胜感激!

我的代码如下:

class _TodosByTagsHomePageState extends State<TodosByTagsHomePage> {
    Tag selectedTag;

    final Logger log = new Logger('TodosByTags');

    @override
    Widget build(BuildContext context) {
      return Scaffold(
          appBar: AppBar(
            title: Text("Second Screen"),
          ),
          body: ListView(
              children: <Widget>[
                FutureBuilder<List<Tag>> (
                    future: fetchTags(),
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        log.info("Tags are present");
                        _tagsList = snapshot.data;
                        return DropdownButton<Tag>(
                          value: selectedTag,
                          items: _tagsList.map((value) {
                            return new DropdownMenuItem<Tag>(
                              value: value,
                              child: Text(value.tagName),
                            );
                          }).toList(),
                          hint: Text("Select tag"),
                          onChanged: (Tag chosenTag) {
                            setState(() {
                              log.info("In set state");
                              selectedTag = chosenTag;
                              Scaffold.of(context).showSnackBar(new SnackBar(content: Text(selectedTag.tagName)));
                            });
                          },
                        ) ;
                      } else if (snapshot.hasError) {
                        return Text("${snapshot.error}");
                      }

                      return Container(width: 0.0, height: 0.0);
                    }),
              ])
      );
    }

// Async method to retrieve data from REST API
      Future<List<Tag>> fetchTags() async {
        final response =
        await http.get(REST_API_URL);

        if (response.statusCode == 200) {
          // If the call to the server was successful, parse the JSON
          var result = compute(parseData, response.body);
          return result;
        } else {
          // If that call was not successful, throw an error.
          throw Exception('Failed to load post');
        }
      }

      static List<Tag> parseData(String response) {
        final parsed = json.decode(response);

        return (parsed["data"] as List).map<Tag>((json) =>
        new Tag.fromJson(json)).toList();
      }

      List<Tag> _tagsList = new List<Tag>();

    }

// Model for Tag
    class Tag {
      final String tagName;
      final String id;
      final int v;

      Tag({this.id, this.tagName, this.v});

      factory Tag.fromJson(Map<String, dynamic> json) {
        return new Tag(
          id: json['_id'],
          tagName: json['tagName'],
          v: json['__v'],
        );
      }
    }

1 个答案:

答案 0 :(得分:0)

像这样更新您的代码 我认为这样的问题是,在setState中调用FutureBuilder的{​​{1}}时,一次调用会将fetchTags()移到fetchTags()

initState()