0

我正在创建一个编辑产品表单,其中数据从 api 获取并填充到未来的构建器中。至于从 中保存新数据TextFormField,我将需要不同的Controllers.

它有不同的 TextFieldsProduct name Product priceProduct Description

所以我想说的是,如果有多个产品,就会有多个Product nameTextFields,它会有多个控制器。

所以我想要实现的是如何在单击按钮时访问不同的ControllersList

假设如果有 4 种不同的产品Furniture Window Glass Artificial GrassModular kitchen当用户点击保存按钮时,所有这些值都应该放在一个列表中,然后发送到数据库。

这是我尝试过的

var productNameControllers = [];

我已经在 Future Builder 中填充了这个列表,并将控制器分配给文本字段

FutureBuilder(
          future: _showData(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                  itemCount: snapshot.data.length,
                  itemBuilder: (BuildContext context, int index) {

                    productNameControllers.add(TextEditingController(
                        text: snapshot.data[index].prodSerName.toString()));
                  
                 return Container(
                    child: TextFormField(
                   controller: productNameControllers[index],
                   decoration: InputDecoration(
                    labelText: "Product Name",
                ),
            ),
                 );
});
}
});

这是访问控制器的代码

  _saveEdits() {
    List savedProds = [];
    for (int i = 0; i < productNameControllers.length; i++) {
      savedProds.add(productNameControllers[i].text);
    }
    print(savedProds);
  }

所以问题是当_saveEdits调用该方法时它只访问前两个控制器值而不是所有值,当我将页面滚动到最后一个产品然后调用该_saveEdits方法时它可以正常工作但为什么它没有访问所有值而不滚动到最后一项。

我想要的输出

访问所有值 [Furniture, Window glass, Artificial Grass, Modular Kitchen]

我得到的输出

只有前两个值 [Furniture, Window glass]

那么我怎样才能实现它。

用 Listview 替换 ListView.builder 之后

FutureBuilder(
          future: _showData(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.hasData) {
              return ListView(
                  children: snapshot.data.map((val) {
                final int index = snapshot.data.indexOf(val);
                productNameControllers
                    .add(TextEditingController(text: val.prodSerName));

                return Container(
                  child: TextFormField(
                    controller: productNameControllers[index],
                    decoration: InputDecoration(
                      labelText: "Product Name",
                    ),
                  ),
                );
              }).toList());
            } else if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(
                child: CircularProgressIndicator(),
              );
            } else {
              return Center(child: Text(snapshot.error.toString()));
            }
          },
        ),
4

1 回答 1

0

ListView.builder 做了一些优化,比如只保存当时在 UI 中显示的对象,而不是所有的值,这是一件好事

我建议不要使用构建器,而是使用默认的 ListView 并执行以下操作

ListView(
children: snapshot.data.map(
(val) {
 
 final int index = snapshot.data.indexOf(val);
 productNameControllers.add(TextEditingController(
                    text: val.prodSerName.toString()));
              
             return Container(
                child: TextFormField(
               controller: productNameControllers[index],
               decoration: InputDecoration(
                labelText: "Product Name",
            ),
        ),
             );
}
).toList()
于 2021-12-23T15:12:59.540 回答