Flutter web,Consumer 重建后的奇怪结果

如何解决Flutter web,Consumer 重建后的奇怪结果

我有一个颤动的表单,其中包含一个带有 textFormFields 行的列。 每行末尾都有一个图标按钮,用于删除所述行。这些行是用消费者构建的。

我有一个通知程序类,其中包含消费者监听的数据。

当按下删除按钮时,通知程序类中的一个函数被调用,负责删除具有给定索引的行。相同的功能是打印出删除前和删除后的数据集。打印效果不错,效果符合预期。

Consumer 还重建了少一行的数据集。但是在 ui 中呈现的数据并不像预期的那样。

在负责构建行的小部件中,我打印出放在 textFormField 的 initialValue 中的数据。印刷品看起来不错,再次符合预期。但是 ui 不会呈现打印显示的内容。 查看图片和代码。

准备删除第二行:

row to be deleted

删除后:

enter image description here

删除行并打印数据的代码。

void deletePoint({int switchpointIndex,int pointIndex,Point point}) {
   for (Switchpoint switchpoint in _settings.switchpoints) {
     for (Point point in switchpoint.points) {
       print("Tag: ${point.tag}. And Type: ${point.type}");
     }
   }
   _settings.switchpoints[switchpointIndex].points.removeAt(pointIndex);
   for (Switchpoint switchpoint in _settings.switchpoints) {
     for (Point point in switchpoint.points) {
       print("Tag: ${point.tag}. And Type: ${point.type}");
     }
   }
   notifyListeners();
}

打印结果(如预期):

标签:并输入:a

标签:b。并输入:b

标签:c。并输入:c

标签:并输入:a

标签:c。并输入:c

打印和呈现行 Widget 中数据的代码:

  @override
Widget build(BuildContext context) {
  print("PointIndex: $pointIndex,value: ${point.tag} and ${point.type}");
  return Row(
  ...
  TextFormField(
  ...
  initialValue: point.tag ?? ''
  ...
  TextFormField(
  ...
  initialValue: point.type ?? ''
  ...

这也会打印预期的内容:

PointIndex: 0,value: a and a

PointIndex:1,值:c 和 c

有人知道发生了什么吗?

-- 编辑 --

没有 TextEditingController。

表格代码:

return Container(
                    padding: EdgeInsets.symmetric(horizontal: 10),child: Form(
                      key: _formKey,child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,children: [
                          SizedBox(
                            height: 50,),Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [
                              Text(
                                'Switchpoint Layout',style: TextStyle(
                                    color: Colors.teal,fontSize: 20,fontWeight: FontWeight.bold),TextButton.icon(
                                  onPressed: () {
                                    context
                                        .read<SettingsNotifier>()
                                        .addEmptySwitchpoint();
                                  },icon: Icon(Icons.add),label: Text('Add Switchpoint')),],Padding(
                            padding: const EdgeInsets.symmetric(horizontal: 10),child: Consumer<SettingsNotifier>(
                                builder: (context,notifier,child) {
                              List<SwitchpointRow> switchpointRows = [];

                              int switchpointIndex = 0;
                              for (Switchpoint switchpoint
                                  in notifier.switchPoints) {
                                switchpointRows.add(SwitchpointRow(
                                  switchpoint: switchpoint,switchpointIndex: switchpointIndex,formKey: _formKey,));
                                switchpointIndex++;
                              }

                              return Column(
                                crossAxisAlignment: CrossAxisAlignment.start,children: [
                                  Column(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.start,children: switchpointRows),);
                            }),Padding(
                            padding: EdgeInsets.symmetric(vertical: 16.0),child: ElevatedButton(
                              onPressed: () async {
                                print(context
                                    .read<SettingsNotifier>()
                                    .settings
                                    .toJson());
                                if (_formKey.currentState.validate()) {}
                              },child: Text('Submit'),);

SwitchpointRow 代码:

class SwitchpointRow extends StatelessWidget {
  const SwitchpointRow({
    Key key,@required this.switchpoint,@required this.switchpointIndex,@required this.formKey,}) : super(key: key);

  final int switchpointIndex;
  final Switchpoint switchpoint;
  final formKey;

  List<PointRow> loadPoints(List<Point> points) {
    List<PointRow> pointRows = [];
    int pointIndex = 0;
    for (Point point in points) {
      pointRows.add(PointRow(
          point: point,pointIndex: pointIndex,last: points.last == point ? true : false));
      pointIndex++;
    }
    return pointRows;
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.only(bottom: 20),child: Column(
          mainAxisSize: MainAxisSize.min,children: [
            AppBar(
              backgroundColor: Colors.amberAccent,title: TextFormField(
                  decoration: InputDecoration(
                    border: InputBorder.none,contentPadding: EdgeInsets.fromLTRB(0,2,4),isDense: true,hintText: 'Switchpoint name',labelText: 'Switchpoint name',initialValue: switchpoint.name ?? '',onChanged: (value) {
                    context
                        .read<SettingsNotifier>()
                        .switchPoints[switchpointIndex]
                        .name = value;
                  },validator: (value) {
                    if (value.isEmpty) {
                      return 'mandatory';
                    }
                    return null;
                  }),actions: [
                Padding(
                  padding: const EdgeInsets.only(right: 18.0),child: TextButton.icon(
                    onPressed: () {
                      context.read<SettingsNotifier>().deleteSwitchpoint(
                          switchpointIndex: switchpointIndex);
                    },icon: Icon(Icons.delete),label: Text('Delete Switchpoint'),Padding(
                  padding: const EdgeInsets.only(right: 8.0),child: TextButton.icon(
                    onPressed: () {
                      context
                          .read<SettingsNotifier>()
                          .addPoint(switchpointIndex);
                    },label: Text('Point'),Padding(
              padding: const EdgeInsets.only(left: 50.0),child: Column(children: loadPoints(switchpoint.points)),);
  }
}

PointRow 代码:

class PointRow extends StatelessWidget {
  const PointRow(
      {Key key,@required this.point,@required this.pointIndex,@required this.last})
      : super(key: key);

  final Point point;
  final int pointIndex;
  final int switchpointIndex;
  final bool last;

  @override
  Widget build(BuildContext context) {
    print("PointIndex: $pointIndex,value: ${point.tag} and ${point.type}");
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [
        Expanded(
          flex: 3,child: TextFormField(
              decoration: InputDecoration(
                contentPadding: EdgeInsets.fromLTRB(0,hintText: 'Tag',labelText: 'Point tag',onChanged: (value) {
                context
                    .read<SettingsNotifier>()
                    .switchPoints[switchpointIndex]
                    .points[pointIndex]
                    .tag = value;
              },initialValue: point.tag ?? '',validator: (value) {
                if (value.isEmpty) {
                  return 'mandatory';
                }
                return null;
              }),SizedBox(width: 30.0),Expanded(
          flex: 3,child: TextFormField(
            decoration: InputDecoration(
              contentPadding: EdgeInsets.fromLTRB(0,hintText: 'Type',labelText: 'Type of point',onChanged: (value) {
              context
                  .read<SettingsNotifier>()
                  .switchPoints[switchpointIndex]
                  .points[pointIndex]
                  .type = value;
            },initialValue: point.type ?? '',Expanded(
          child: IconButton(
            padding: EdgeInsets.all(0.0),onPressed: () {
              context.read<SettingsNotifier>().deletePoint(
                  switchpointIndex: switchpointIndex,point: point);
            },)
      ],);
  }
}

整个Form图片:

enter image description here

解决方法

因此,经过反复试验,解决方案必须是 TextEditingController,我想避免使用它,因为最终会有几个字段。

所以解决方案是一个像这样的内联控制器:

TextFormField(
   ...
   controller: TextEditingController()..text = 'the value',...
);

这样,用户界面就会按照我的意愿行事。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-