问题
I am having a data update screen where the user can update/edit data saved in database. I have multiple fields which the user can edit. The data is prefilled with the previous value saved in database. My edit screen is as follows
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: newdrawer(),
appBar: newappbar(
title: 'Edit Task',
),
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(),
child: Center(
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Title',
),
initialValue: widget.postid.data['Title'],
onChanged: (value){
this.Title=value;
},
),
SizedBox(height: 5.0),
Container(
height: maxLines * 24.0,
child: TextFormField(
maxLines: maxLines,
decoration: InputDecoration(
hintText: 'Enter Summary',
contentPadding: new EdgeInsets.symmetric(
vertical: 25.0, horizontal: 10.0),
),
initialValue: widget.postid.data['Summary'],
onChanged: (value) {
this.Summary = value;
},
),
),
SizedBox(height: 5.0),
SizedBox(height: 5.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Task to be given to',
contentPadding: new EdgeInsets.symmetric(
vertical: 25.0, horizontal: 10.0),
),
initialValue: widget.postid.data['Taskgivento'],
//TODO: use tagging system or search when typed system
onChanged: (value) {
this.Taskgivento = value;
},
),
SizedBox(height: 5.0),
TextFormField(
decoration: InputDecoration(
hintText: 'Status',
contentPadding: new EdgeInsets.symmetric(
vertical: 25.0, horizontal: 10.0),
),
initialValue: widget.postid.data['Status'],
onChanged: (value) {
this.Status = value;
},
),
DateTimeField(
format: dateformat,
onShowPicker: (context, currentValue) {
return showDatePicker(
context: context,
firstDate: DateTime(1900),
initialDate: currentValue ?? DateTime.now(),
lastDate: DateTime(2100));
},
decoration: InputDecoration(
hintText: 'Enter Date to be completed',
contentPadding: new EdgeInsets.symmetric(
vertical: 25.0, horizontal: 10.0),
),
initialValue: widget.postid.data['Completion'].toDate(),
onChanged: (value) {
this.Completion = value;
},
),
SizedBox(height: 25.0),
SizedBox(
width: 90.0,
height: 50.0,
child: FlatButton(
//color: Colors.blue,
padding: EdgeInsets.all(8.0),
child: Text('Update Task'),
onPressed: () {
Firestore.instance.collection('Task').document(_postdocid()).updateData({
'Title': this.Title,
'Summary': this.Summary,
'Taskgivento': this.Taskgivento,
'Status': this.Status,
'Completion': this.Completion,
});
Navigator.of(context).pop();
},
),
)
],
),
),
),
));
}
}
I have five fields that can be edited but say the user only edits the Title field and press update button then the rest of the fields are saving as null as they are not changed. But i want to be the same as their previous values (initial value) . I tried to use if else statement in on-changed but that isnt working. What can i do to achieved this?
回答1:
When you update a document, Firestore will set the fields you specify in that call to the value you specified. So if a field should not be updated, you should not include it in the call.
That means you should build a map of only the fields thathave a new value, and pass that map to Firestore. Something like:
Map<String, Object> data = new HashMap();
if (this.Title) data['Title'] = this.Title;
if (this.Summary) data['Summary'] = this.Summary;
if (this.Taskgivento) data['Taskgivento'] = this.Taskgivento;
if (this.Status) data['Status'] = this.Status;
if (this.Completion) data['Completion'] = this.Completion;
Firestore.instance.collection('Task').document(_postdocid()).updateData(data);
来源:https://stackoverflow.com/questions/61836579/value-of-firebase-database-updating-to-null-when-not-not-edited-during-update-da