【问题标题】:There should be exactly one item with [DropdownButton]'s value应该只有一项具有 [DropdownButton] 的值
【发布时间】:2021-05-01 01:23:03
【问题描述】:

我正在为电子商务系统构建一个应用程序,该应用程序可以将数据发布到服务器。有多个项目类别具有不同的和可自定义的值。例如,笔记本电脑类别可以具有处理器、内存、存储大小属性。其中一些属性是文本框(例如模型),而其他属性需要是下拉列表(例如处理器 - 核心 i7、i5 等...)。属性的数量不能固定,因为它取决于类别(可能随时添加或删除)

我正在尝试构建一个表单,该表单将根据属性类型(AttributeType 列)将此属性显示为文本框或下拉列表。我能够显示文本框和下拉列表(成功显示它们的元素。我遇到的问题是访问下拉值以创建对服务器的发布请求。

这里是代码

 FutureBuilder<FormListModel>(
                future: _formList,
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    return ListView.builder(
                      primary: false,
                      scrollDirection: Axis.vertical,
                      shrinkWrap: true,
                      itemCount: snapshot.data.customattributes.length,
                      itemBuilder: (context, index) {
                        var item = snapshot.data.customattributes[index];
                        print(item.name);
                        
                        if (item.AttributeType == 'Text') {
                          return Container(
                            //padding: EdgeInsets.only(top: 8),
                            margin:
                                EdgeInsets.only(top: 15, left: 15, right: 15),
                            child: Column(
                              children: [
                                Form(
                                  child: TextFormField(
                                    controller: model_controller,
                                    decoration: InputDecoration(
                                      contentPadding: EdgeInsets.symmetric(
                                          vertical: 10, horizontal: 10),
                                      labelText: item.name,
                                      border: OutlineInputBorder(
                                        borderSide: BorderSide(
                                            color: Colors.blueAccent),
                                      ),
                                    ),
                                    onChanged: (value) {
                                      //print(model_controller.text);
                                    },
                                  ),
                                ),
                              ],
                            ),
                          );
                        } else if (item.AttributeType == 'Selectlist') {
                          return Container(
                            //padding: EdgeInsets.only(top: 8),
                            margin:
                                EdgeInsets.only(top: 20, left: 15, right: 15),
                            child: Column(
                              children: [
                                Form(
                                  child: InputDecorator(
                                    decoration: InputDecoration(
                                      contentPadding: EdgeInsets.symmetric(
                                          vertical: 12, horizontal: 12),
                                      labelText: item.name,
                                      labelStyle: TextStyle(
                                          fontSize: 20,
                                          color: Colors.blueAccent),
                                      border: const OutlineInputBorder(),
                                    ),
                                    child: DropdownButtonHideUnderline(
                                      child: DropdownButton(
                                        isDense: true,
                                        icon: Icon(Icons.keyboard_arrow_down),
                                        value: selectedAttribute,
                                        onChanged: (newValue) {
                                          setState(() {
                                            selectedAttribute = newValue;
                                          });
                                        },
                                        //decoration: InputDecoration(border: InputBorder.none),
                                        items: item.children
                                            .map<DropdownMenuItem>((items) {
                                          return DropdownMenuItem<String>(
                                            child: Row(
                                              children: [
                                                Padding(
                                                  padding:
                                                      EdgeInsets.only(top: 7),
                                                  child: Text(items.element),
                                                ),
                                              ],
                                            ),
                                            value: items.element,
                                          );
                                        }).toList(),
                                      ),
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          );
                        } else {
                          return null;
                        }
                      },
                    );
                  } else {
                    return Container();
                  }
                }),

这是我们从服务器获取的用于使用 ListView.builder 创建表单的 json 文件

{
    "category": {
        "CategoryName": "Laptops",
        "CategoryID": 34
    },
    "customattributes": [
        {
            "Name": "Model",
            "AttributeType": "Text",
            "AttributeID": 7
        },
        {
            "Name": "Processor",
            "AttributeType": "Selectlist",
            "AttributeID": 2,
            "Children": [
                {
                    "Element": "Intel Core i3"
                },
                {
                    "Element": "Intel Core i5"
                },
                {
                    "Element": "Intel Core i7"
                }
            ]
        },
        {
            "Name": "Storage Size",
            "AttributeType": "Selectlist",
            "AttributeID": 1,
            "Children": [                
                {
                    "Element": "1TB"
                },
                {
                    "Element": "2TB"
                },
                {
                    "Element": "2.5TB"
                }
            ]
        },
        {
            "Name": "RAM",
            "AttributeType": "Selectlist",
            "AttributeID": 3,
            "Children": [
                {
                    "Element": "12GB"
                },
                {
                    "Element": "16GB"
            ]
        }
    ],
    
}

这是表格

当我从下拉列表中选择任何值时,我收到一条错误消息,提示应该只有一项具有 [DropdownButton] 的值

  1. 那么如何访问每个下拉列表的值,以便向服务器发出 http post 请求。请记住,每个类别的下拉菜单(属性)的数量是不同的。 第二个问题,不是那么重要,但有没有一种方法可以使用 json 文件中属性的“名称”列为每个下拉列表分配一个名称。

【问题讨论】:

    标签: flutter dart drop-down-menu flutter-futurebuilder


    【解决方案1】:

    在onChanged方法中改变下拉值时尝试将其他下拉值设置为null

    【讨论】:

    • 这是为了避免看到错误还是访问值?因为,如果用户已经从下拉列表中选择了一个值,我很确定将其他下拉列表值设置为 null 没有任何意义。
    • 我很确定 null 会起作用,因为它过去对我有用
    【解决方案2】:

    问题在于分配的值和下拉列表的项目列表。

    请注意,下拉菜单的值只能是下拉菜单项中的值。对于自定义值,您必须比较所选项目的值并将项目的索引作为当前值。希望你能理解我的担忧。

    按照以下代码:

    value : getSelectedValue(yourValue);
    ...
    getSelectedValue(yourValue){
        //add this line of code
        if(yourValue == null) return null;
        for(value in dropDownItems){
            if(value.id == yourValue.id) return value;
        }
        return null;
    }
    

    【讨论】:

    • 我试过你的代码,它说 The getter 'attributeid' was called on null。接收者:null 尝试调用:attributeid
    • 我已经编辑了答案。请检查一下。
    【解决方案3】:

    我也有同样的问题... 我设法通过检查我的列表是否为空来解决它。如果是,我将值设置为 null,否则选择列表中的第一项

    value: Provider.of<DepositProvider>(context)
                              .paymentMethods.isNotEmpty ?Provider.of<DepositProvider>(context)
                              .paymentMethods.first : null,
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-17
      • 2021-08-29
      • 2020-06-16
      • 1970-01-01
      • 2020-07-18
      • 2020-08-26
      • 2021-12-03
      • 2021-11-05
      相关资源
      最近更新 更多