Firebase 颤振:从对象编辑新对象错误地更改旧对象

Firebase 颤振:从对象编辑新对象错误地更改旧对象,firebase,flutter,google-cloud-firestore,flutter-provider,flutter-showmodalbottomsheet,Firebase,Flutter,Google Cloud Firestore,Flutter Provider,Flutter Showmodalbottomsheet,我正在尝试在我的生产力跟踪应用程序中包含“编辑对象”功能。我正在使用Flutter、Firestore和Provider。我试图允许用户在模式底部工作表中更新具有不同属性的任务(例如)。更新方面正在工作。如果用户按下更新按钮,则会正确更新Firestore并正确显示信息。我的问题是,当我在模式外取消时,发出取消更新的信号,它仍然在更新原始任务对象。我甚至试着用一个取消按钮来处理提供者,结果是一样的。我不知道为什么会这样。如果重新加载应用程序,则会显示存储在Firestore中的正确值。以下是正在

我正在尝试在我的生产力跟踪应用程序中包含“编辑对象”功能。我正在使用Flutter、Firestore和Provider。我试图允许用户在模式底部工作表中更新具有不同属性的任务(例如)。更新方面正在工作。如果用户按下更新按钮,则会正确更新Firestore并正确显示信息。我的问题是,当我在模式外取消时,发出取消更新的信号,它仍然在更新原始任务对象。我甚至试着用一个取消按钮来处理提供者,结果是一样的。我不知道为什么会这样。如果重新加载应用程序,则会显示存储在Firestore中的正确值。以下是正在发生的事情的视频:

这是我的任务模型:

class Task {
  String taskID;
  String taskName;
  Project project;
  Status status;
  DateTime dueDate;
  DateTime createDate;

  Task({taskID, taskName, project, status, dueDate, createDate})
      : taskID = taskID as String ?? '',
        taskName = taskName as String ?? '',
        project = project as Project ?? Project(),
        status = status as Status ?? Status(),
        dueDate = dueDate as DateTime ?? DateTime(0001, 01, 01, 0, 0, 0, 0, 555),
        createDate = createDate as DateTime ?? DateTime.now();
这是我的提供者状态:

class TaskEditState extends ChangeNotifier {
  Task newTask;

  TaskEditState({newTask}) : newTask = newTask as Task ?? Task();

  void updateTaskName(String taskName) {
    newTask.taskName = taskName;
    notifyListeners();
  }

  void updateTaskProject(Project project) {
    newTask.project = project;
    notifyListeners();
  }

  void updateTaskStatus(Status status) {
    newTask.status = status;
    notifyListeners();
  }

  void updateTaskDueDate(DateTime dueDate) {
    if (newTask.dueDate.microsecond == 555) {
      newTask.dueDate = dueDate;
    } else {
      final DateTime temp = newTask.dueDate;
      newTask.dueDate = DateTime(
          dueDate.year, dueDate.month, dueDate.day, temp.hour, temp.minute);
    }
    notifyListeners();
  }

  void updateTaskDueTime(TimeOfDay dueTime) {
    if (newTask.dueDate.year == 0) {
      newTask.dueDate = DateTime(0, 0, 0, dueTime.hour, dueTime.minute);
    } else {
      final DateTime temp = newTask.dueDate;
      newTask.dueDate = DateTime(
          temp.year, temp.month, temp.day, dueTime.hour, dueTime.minute);
    }
    notifyListeners();
  }

  void addTaskCreateDate(DateTime createDate) {
    newTask.createDate = createDate;
  }
这是我的编辑底稿

  TaskEditBottomSheet({
    Key key,
    this.isUpdate,
    this.task,
  }) : super(key: key);

  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => TaskEditState(newTask: task),
      builder: (context, child) {
        final TaskEditState taskEditState = Provider.of<TaskEditState>(context);
        final TaskService taskService = Provider.of<TaskService>(context);
        print(taskEditState.newTask.project.projectName);
        return Container(
            margin: EdgeInsets.all(20),
            child: Column(mainAxisSize: MainAxisSize.min, children: [
              TextFormField(
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Please Enter Project Name';
                  }
                  return null;
                },
                decoration: InputDecoration(
                    hintText: taskEditState.newTask.taskName.isEmpty
                        ? 'Enter Task Name'
                        : taskEditState.newTask.taskName),
                textAlign: TextAlign.center,
                onChanged: (newText) {
                  taskEditState.updateTaskName(newText);
                },
              ),
              ProjectPicker(
                saveProject: taskEditState.updateTaskProject,
                child: ListTile(
                  leading: Icon(
                    Icons.circle,
                    color: Color(taskEditState.newTask.project.projectColor),
                  ),
                  title: Text(
                      taskEditState.newTask.project.projectName.isEmpty
                          ? 'Add Project'
                          : taskEditState.newTask.project.projectName,
                      style: Theme.of(context).textTheme.subtitle1),
                  trailing: Icon(Icons.arrow_drop_down_rounded,
                      color: Theme.of(context).unselectedWidgetColor),
                ),
              ),
              StatusPicker(saveStatus: taskEditState.updateTaskStatus),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  Text('Due: ', style: Theme.of(context).textTheme.subtitle1),
                  OutlinedButton.icon(
                    onPressed: () => DateAndTimePickers().selectDate(
                        context: context,
                        initialDate: taskEditState.newTask.dueDate.year == 1
                            ? DateTime.now()
                            : taskEditState.newTask.dueDate,
                        saveDate: taskEditState.updateTaskDueDate),
                    icon: Icon(Icons.today_rounded),
                    label: Text(taskEditState.newTask.dueDate.year == 1
                        ? 'Add Due Date'
                        : DateTimeFunctions().dateTimeToTextDate(
                            date: taskEditState.newTask.dueDate)),
                  ),
                  OutlinedButton.icon(
                    onPressed: () => DateAndTimePickers().selectTime(
                        context: context,
                        initialTime:
                            taskEditState.newTask.dueDate.microsecond == 555
                                ? TimeOfDay.now()
                                : TimeOfDay.fromDateTime(
                                    taskEditState.newTask.dueDate),
                        saveTime: taskEditState.updateTaskDueTime),
                    icon: Icon(Icons.alarm_rounded),
                    label: Text(taskEditState.newTask.dueDate.microsecond != 555
                        ? DateTimeFunctions().dateTimeToTextTime(
                            date: taskEditState.newTask.dueDate,
                            context: context)
                        : 'Add Due Time'),
                  ),
                ],
              ),
              Container(
                padding: EdgeInsets.symmetric(vertical: 20),
                child:
                    ElevatedButton.icon(
                  icon: Icon(Icons.check_circle_outline_rounded),
                  label: Text(isUpdate ? 'Update' : 'Add'),
                  onPressed: () {
                    if (_formKey.currentState.validate()) {
                      isUpdate
                          ? taskService.updateTask(
                              taskID: task.taskID,
                              updateData: taskEditState.newTask.toFirestore())
                          : taskService.addTask(
                              addData: taskEditState.newTask.toFirestore());
                      Navigator.pop(context);
                    }
                  },
                ),
              )
            ]));
      },
    );
  }
}
TaskEditBottomSheet({
关键点,
这个.isUpdate,
这个任务,,
}):super(key:key);
最终的GlobalKey _formKey=GlobalKey();
@凌驾
小部件构建(构建上下文){
返回ChangeNotifierProvider(
创建:(上下文)=>TaskEditState(newTask:task),
生成器:(上下文,子对象){
final TaskEditState TaskEditState=Provider.of(上下文);
final TaskService TaskService=Provider.of(上下文);
打印(taskEditState.newTask.project.projectName);
返回容器(
保证金:全部(20),
子项:列(mainAxisSize:mainAxisSize.min,子项:[
TextFormField(
验证器:(值){
if(value==null | | value.isEmpty){
返回“请输入项目名称”;
}
返回null;
},
装饰:输入装饰(
hintText:taskEditState.newTask.taskName.isEmpty
?“输入任务名称”
:taskEditState.newTask.taskName),
textAlign:textAlign.center,
一旦更改:(新文本){
taskEditState.updateTaskName(newText);
},
),
投影仪选择器(
saveProject:taskEditState.updateTaskProject,
孩子:ListTile(
领先:图标(
图标。圆圈,
颜色:颜色(taskEditState.newTask.project.projectColor),
),
标题:正文(
taskEditState.newTask.project.projectName.isEmpty
?“添加项目”
:taskEditState.newTask.project.projectName,
风格:Theme.of(context.textTheme.subtitle1),
尾随:图标(图标。箭头\下拉\四舍五入,
颜色:主题.of(上下文).unselectedWidgetColor),
),
),
状态选择器(保存状态:taskEditState.updateTaskStatus),
划船(
mainAxisAlignment:mainAxisAlignment.spaceAround,
儿童:[
Text('Due:',style:Theme.of(context).textTheme.subtitle1),
OutlinedButton.icon(
按下时:()=>DateAndTimePickers()。选择日期(
上下文:上下文,
initialDate:taskEditState.newTask.dueDate.year==1
?DateTime.now()
:taskEditState.newTask.dueDate,
保存日期:taskEditState.updateTaskDueDate),
图标:图标(今天的图标),
标签:文本(taskEditState.newTask.dueDate.year==1
?“添加到期日”
:DateTimeFunctions().dateTimeToTextDate(
日期:taskEditState.newTask.dueDate),
),
OutlinedButton.icon(
按下时:()=>DateAndTimePickers()。选择时间(
上下文:上下文,
初始时间:
taskEditState.newTask.dueDate.microsecond==555
?一天的时间。现在()
:TimeOfDay.fromDateTime(
taskEditState.newTask.dueDate),
保存时间:taskEditState.updateTaskDueTime),
图标:图标(图标。报警四舍五入),
标签:文本(taskEditState.newTask.dueDate.microsecond!=555
?DateTimeFunctions().dateTimeToTextTime(
日期:taskEditState.newTask.dueDate,
上下文:上下文)
:“添加到期时间”),
),
],
),
容器(
填充:边缘组。对称(垂直:20),
儿童:
ElevatedButton.icon(
图标:图标(图标。勾选“圆形”\u“轮廓”\u“圆形”),
标签:文本(isUpdate?'Update':'Add'),
已按下:(){
if(_formKey.currentState.validate()){
isUpdate
?taskService.updateTask(
taskID:task.taskID,
updateData:taskEditState.newTask.toFirestore())
:taskService.addTask(
addData:taskEditState.newTask.toFirestore());
Navigator.pop(上下文);
}
},
),
)
]));
},
);
}
}
最后,这是调用底部工作表的函数:

class EditBottomSheet {
  Future<dynamic> buildEditBottomSheet(
      {BuildContext context, Widget bottomSheet}) {
    return showModalBottomSheet(
        context: context,
        enableDrag: true,
        // isDismissible: false,
        isScrollControlled:
            true, // Allows the modal to me dynamic and keeps the menu above the keyboard
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.only(
                topLeft: Radius.circular(25), topRight: Radius.circular(25))),
        builder: (BuildContext context) {
          return bottomSheet;
        });
  }
}
class编辑器底页{
未来建筑设计底图(
{BuildContext上下文,小部件底部页}){
返回showModalBottomSheet(
上下文:c
TaskEditState({newTask}) : newTask = newTask as Task ?? Task();
TaskEditState({this.oldTask}) {
    if (oldTask != null) {
      newTask = oldTask.copyTask();
    } else {
      newTask = Task();
    }
  }
Task copyTask() {
    return Task(
        id: id ?? '',
        taskName: taskName ?? '',
        project: project ?? Project(),
        status: status ?? Status(),
        dueDate: dueDate ?? DateTime(0001, 01, 01, 0, 0, 0, 0, 555),
        createDate: createDate ?? DateTime.now());
  }