Flutter:当列表数据更改时,getx 控制器未更新。我如何确保添加的每个列表,GetX 控制器都知道这一点?

Posted

技术标签:

【中文标题】Flutter:当列表数据更改时,getx 控制器未更新。我如何确保添加的每个列表,GetX 控制器都知道这一点?【英文标题】:Flutter: getx controller not updated when list data changed. How can i make sure with every list added, GetX controller knows that? 【发布时间】:2021-07-15 07:21:03 【问题描述】:

我只是在步进器中有一个表单,有两个字段名称和电子邮件。添加按钮可以正常工作,并按预期将名称和电子邮件添加到列表中。当我点击保存时,会打印 JSON 数据以及列表中的所有可用数据。

["Name":"first language","Email":"first value","Name":"second language","Email":"second value","Name":"third language","Email":"third value","Name":"test","Email":"test"]

但是,当我点击底部的保存按钮时,打印的是硬编码列表,而不是我们输入的数据。

输出如下。我想获取 JSON 中的所有列表数据。目前,以下没有从列表中手动插入的数据。:

"User Data":["Name":"first language","Email":"first value","Name":"second language","Email":"second value","Name":"third language","Email":"third value"]

代码如下:-

    model.dart
    class User 
      String name;
      String email;
    
      User(this.name, this.email);
    
      Map toJson() => 
            'Name': name,
            'Email': email,
          ;
    

class JSONGenerate 
  List<User> userData;

  JSONGenerate([this.userData]);

  Map toJson() 
    List<Map> userData = this.userData != null
        ? this.userData.map((i) => i.toJson()).toList()
        : null;

    return 
      'User Data': userData,
    ;
  
 
    User.dart
class UserMinor extends StatefulWidget 
  @override
  _UserMinorState createState() => _UserMinorState();


class _UserMinorState extends State<UserMinor> 
  final form = GlobalKey<FormState>();
  static var _focusNode = new FocusNode();
  // finding same instance if initialized controller
  final controller = Get.find<UserMinorController>();
  @override
  Widget build(BuildContext context) 
    Widget bodyData() => DataTable(
          onSelectAll: (b) ,
          sortColumnIndex: 0,
          sortAscending: true,
          columns: <DataColumn>[
            DataColumn(label: Text("User Name"), tooltip: "User Name"),
            DataColumn(label: Text("User Email"), tooltip: "User Email"),
          ],
          rows: controller.userList // accessing list from Getx controller
              .map(
                (user) => DataRow(
                  cells: [
                    DataCell(
                      Text(user.name),
                    ),
                    DataCell(
                      Text(user.email),
                    ),
                  ],
                ),
              )
              .toList(),
        );

    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Column(
        children: <Widget>[
          Padding(
            padding: EdgeInsets.all(10.0),
            child: Form(
              key: form,
              child: Container(
                child: Column(
                  children: <Widget>[
                    TextFormField(
                      controller: controller.nameController,
                      focusNode: _focusNode,
                      keyboardType: TextInputType.text,
                      autocorrect: false,
                      maxLines: 1,
                      validator: (value) 
                        if (value.isEmpty) 
                          return 'This field is required';
                        
                        return null;
                      ,
                      decoration: InputDecoration(
                        labelText: 'Name',
                        hintText: 'Name',
                        labelStyle: new TextStyle(
                            decorationStyle: TextDecorationStyle.solid),
                      ),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    TextFormField(
                      controller: controller.emailController,
                      keyboardType: TextInputType.text,
                      autocorrect: false,
                      maxLines: 1,
                      validator: (value) 
                        if (value.isEmpty) 
                          return 'This field is required';
                        
                        return null;
                      ,
                      decoration: InputDecoration(
                          labelText: 'Email',
                          hintText: 'Email',
                          labelStyle: new TextStyle(
                              decorationStyle: TextDecorationStyle.solid)),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    Column(
                      children: <Widget>[
                        Center(
                          child: Row(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              Row(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: <Widget>[
                                  TextButton(
                                    child: Text("Add"),
                                    onPressed: () 
                                      if (validate() == true) 
                                        form.currentState.save();
                                        controller.addLanguagetoList(
                                          controller.nameController.text,
                                          controller.emailController.text,
                                        );
                                      
                                    ,
                                  ),
                                  ElevatedButton(
                                      child: Text("Save"),
                                      onPressed: () 
                                        form.currentState.save();
                                        String minorlanguageListJson =
                                            jsonEncode(controller.userList);
                                        print(minorlanguageListJson);
                                      ),
                                ],
                              ),
                            ],
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          ),
          // GetBuilder rebuilds when update() is called
          GetBuilder<UserMinorController>(
            builder: (controller) => bodyData(),
          ),
        ],
      ),
    );
  

  bool validate() 
    var valid = form.currentState.validate();
    if (valid) form.currentState.save();
    return valid;
  

    stepper.dart
class StepperBody extends StatefulWidget 
  @override
  _StepperBodyState createState() => new _StepperBodyState();


class _StepperBodyState extends State<StepperBody> 
  int currStep = 0;
  static var _focusNode = new FocusNode();
  GlobalKey<FormState> _formKey = new GlobalKey<FormState>();

  @override
  void initState() 
    super.initState();
    _focusNode.addListener(() 
      setState(() );
      print('Has focus: $_focusNode.hasFocus');
    );
  

  @override
  void dispose() 
    _focusNode.dispose();
    super.dispose();
  

  List<Step> steps = [
    new Step(
      title: const Text('Technical Language Basics'),
      isActive: true,
      state: StepState.indexed,
      content: UserMinor(),
    ),
  ];

  @override
  Widget build(BuildContext context) 
    return Container(
      child: new Form(
        key: _formKey,
        child: new ListView(
          children: <Widget>[
            new Stepper(
              steps: steps,
              type: StepperType.vertical,
              currentStep: this.currStep,
              onStepContinue: () 
                setState(() 
                  if (currStep < steps.length - 1) 
                    currStep = currStep + 1;
                   else 
                    currStep = 0;
                  
                );
              ,
              onStepCancel: () 
                setState(() 
                  if (currStep > 0) 
                    currStep = currStep - 1;
                   else 
                    currStep = 0;
                  
                );
              ,
              onStepTapped: (step) 
                setState(() 
                  currStep = step;
                );
              ,
            ),
            new ElevatedButton(
              child: new Text(
                'Save details',
                style: new TextStyle(color: Colors.white),
              ),
              onPressed: () 
                var technicalInfo = UserMinorController().userList;
                JSONGenerate jsonGenerate = JSONGenerate(technicalInfo);
                print(
                  jsonEncode(jsonGenerate),
                );
              ,
            ),
          ],
        ),
      ),
    );
  

    GetX 控制器类
    class UserMinorController extends GetxController 
      TextEditingController nameController = TextEditingController();
      TextEditingController emailController = TextEditingController();
      int currentIndex = 0;
    
      List<User> userList = [
        User(name: "first language", email: "first value"),
        User(name: "second language", email: "second value"),
        User(name: "third language", email: "third value"),
      ];
    
    
    
      void addLanguagetoList(name, email) 
        userList.add(User(name: name, email: email));
        update();
      
    

【问题讨论】:

你能分享你的 GetX 课程吗? @Loren.A..我添加了 GetX 类。我希望这会有所帮助。感谢您的回复:) 【参考方案1】:

这是这里的问题:

var technicalInfo = UserMinorController().userList;

在 GetX 中,您需要使用Get.find&lt;UserMinorController&gt;()“找到”相同的控制器实例。这将找到具有您要添加到的实际列表的同一实例。你这样做的方式是打印出一个不同的实例UserMinorController,这就是为什么它只打印出硬编码数据。

您的onPressed 应该如下所示。

 onPressed: () 
   var technicalInfo = Get.find<UserMinorController>().userList;
   JSONGenerate jsonGenerate = JSONGenerate(technicalInfo);
   print(jsonEncode(jsonGenerate));

【讨论】:

非常感谢您的帮助。我非常感谢。 没问题,乐于助人。 你能检查一下吗? ***.com/questions/67281290/… 抱歉,我没有使用 AWS 的经验,只有 Firebase。我想您要问的是文档中的内容,但是请深入研究一下。如果您真的无法弄清楚,请考虑尝试 Firebase。我之所以这么说是因为 Flutter Firebase 文档非常好,如果您遇到困难,Stack Overflow 上的很多人应该能够帮助您。 感谢您的建议。我将在我的 AWS 服务器上托管它,并且我想将生成的文件保存在 s3 存储桶中。所以,我不得不在 AWS 服务器上做。但我会记住你的建议:) ...非常感谢

以上是关于Flutter:当列表数据更改时,getx 控制器未更新。我如何确保添加的每个列表,GetX 控制器都知道这一点?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter GetX 为啥控制器在导航时没有自动删除

Flutter 监听 Stateless Widget 上的生命周期事件?

Flutter Getx - 更新子列表中的项目不是反应性的

即使收到更新的数据,Flutter ListView.builder 的 UI 也不会被 getx 更新

Flutter状态管理终极方案GetX第二篇——状态管理

使用 GetX 改变主题?