Skip to content

Commit 000f969

Browse files
committed
reworked form value caching
1 parent 7e86a22 commit 000f969

File tree

2 files changed

+95
-26
lines changed

2 files changed

+95
-26
lines changed

packages/flutter_form_builder/lib/src/form_builder.dart

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -86,20 +86,62 @@ class FormBuilderState extends State<FormBuilder> {
8686

8787
final _fields = <String, FormBuilderFieldState>{};
8888

89-
final _value = <String, dynamic>{};
89+
final _transformers = <String, dynamic Function(Object?)>{};
90+
final _instantValue = <String, dynamic>{};
91+
final _savedValue = <String, dynamic>{};
9092

91-
Map<String, dynamic> get value => Map<String, dynamic>.unmodifiable(_value);
93+
Map<String, dynamic> get instantValue =>
94+
Map<String, dynamic>.unmodifiable(_instantValue.map((key, value) =>
95+
MapEntry(key, _transformers[key]?.call(value) ?? value)));
9296

97+
/// Returns the saved value only
98+
Map<String, dynamic> get value =>
99+
Map<String, dynamic>.unmodifiable(_savedValue.map((key, value) =>
100+
MapEntry(key, _transformers[key]?.call(value) ?? value)));
101+
102+
/// Returns values after saving
93103
Map<String, dynamic> get initialValue => widget.initialValue;
94104

95105
Map<String, FormBuilderFieldState> get fields => _fields;
96106

97-
void setInternalFieldValue(String name, dynamic value) {
98-
setState(() => _value[name] = value);
107+
dynamic transformValue<T>(String name, T? v) {
108+
final t = _transformers[name];
109+
return t != null ? t.call(v) : v;
110+
}
111+
112+
dynamic getTransformedValue<T>(String name, {bool fromSaved = false}) {
113+
final og = fromSaved ? _savedValue[name] : _instantValue[name];
114+
return transformValue<T>(name, og);
99115
}
100116

101-
void removeInternalFieldValue(String name) {
102-
setState(() => _value.remove(name));
117+
T? getRawValue<T>(String name, {bool fromSaved = false}) {
118+
return fromSaved ? _savedValue[name] : _instantValue[name];
119+
}
120+
121+
void setInternalFieldValue<T>(
122+
String name,
123+
T? value, {
124+
required dynamic Function(T?)? transformer,
125+
required bool isSetState,
126+
}) {
127+
_instantValue[name] = value;
128+
129+
if (transformer != null) {
130+
_transformers[name] = (val) => transformer(val as T?);
131+
}
132+
if (isSetState) {
133+
setState(() {});
134+
}
135+
}
136+
137+
void removeInternalFieldValue(
138+
String name, {
139+
required bool isSetState,
140+
}) {
141+
_instantValue.remove(name);
142+
if (isSetState) {
143+
setState(() {});
144+
}
103145
}
104146

105147
void registerField(String name, FormBuilderFieldState field) {
@@ -121,30 +163,26 @@ class FormBuilderState extends State<FormBuilder> {
121163
_fields[name] = field;
122164
if (oldField != null) {
123165
// ignore: invalid_use_of_protected_member
124-
field.setValue(oldField.value);
125-
_tempFieldValues.remove(name);
166+
field.setValue(
167+
oldField.value,
168+
populateForm: false,
169+
);
126170
} else {
127-
final oldTemp = _tempFieldValues[name];
128-
if (oldTemp != null) {
129-
// ignore: invalid_use_of_protected_member
130-
field.setValue(oldTemp);
131-
_tempFieldValues.remove(name);
132-
} else {
133-
// ignore: invalid_use_of_protected_member
134-
field.setValue(field.initialValue);
135-
}
171+
// ignore: invalid_use_of_protected_member
172+
field.setValue(
173+
_instantValue[name] ?? field.initialValue,
174+
populateForm: false,
175+
);
136176
}
137177
}
138178

139-
final _tempFieldValues = <String, dynamic>{};
140179
void unregisterField(String name, FormBuilderFieldState field) {
141180
assert(_fields.containsKey(name));
142181
// Only remove the field when it is the one registered. It's possible that
143182
// the field is replaced (registerField is called twice for a given name)
144183
// before unregisterField is called for the name, so just emit a warning
145184
// since it may be intentional.
146185
if (field == _fields[name]) {
147-
_tempFieldValues[name] = field.value;
148186
_fields.remove(name);
149187
} else {
150188
assert(() {
@@ -156,11 +194,14 @@ class FormBuilderState extends State<FormBuilder> {
156194
}());
157195
}
158196
// Removes internal field value
159-
_value.remove(name);
197+
// _savedValue.remove(name);
160198
}
161199

162200
void save() {
163201
_formKey.currentState!.save();
202+
//copy values from instant to saved
203+
_savedValue.clear();
204+
_savedValue.addAll(_instantValue);
164205
}
165206

166207
void invalidateField({required String name, String? errorText}) =>

packages/flutter_form_builder/lib/src/form_builder_field.dart

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
100100

101101
FormBuilderState? _formBuilderState;
102102

103+
dynamic get transformedValue => widget.valueTransformer?.call(value) ?? value;
104+
103105
@override
104106
String? get errorText => super.errorText ?? _customErrorText;
105107

@@ -138,17 +140,30 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
138140
super.dispose();
139141
}
140142

141-
@override
142-
void save() {
143-
super.save();
143+
// @override
144+
// void save() {
145+
// _informFormForFieldChange(
146+
// isSetState: true,
147+
// );
148+
// super.save();
149+
// }
150+
151+
void _informFormForFieldChange({
152+
required bool isSetState,
153+
}) {
144154
if (_formBuilderState != null) {
145155
if (enabled || !_formBuilderState!.widget.skipDisabled) {
146-
_formBuilderState!.setInternalFieldValue(
156+
_formBuilderState!.setInternalFieldValue<T>(
147157
widget.name,
148-
widget.valueTransformer?.call(value) ?? value,
158+
value,
159+
transformer: widget.valueTransformer,
160+
isSetState: isSetState,
149161
);
150162
} else {
151-
_formBuilderState!.removeInternalFieldValue(widget.name);
163+
_formBuilderState!.removeInternalFieldValue(
164+
widget.name,
165+
isSetState: isSetState,
166+
);
152167
}
153168
}
154169
}
@@ -159,9 +174,22 @@ class FormBuilderFieldState<F extends FormBuilderField<T>, T>
159174
}
160175
}
161176

177+
@override
178+
void setValue(T? value, {bool populateForm = true}) {
179+
super.setValue(value);
180+
if (populateForm) {
181+
_informFormForFieldChange(
182+
isSetState: false,
183+
);
184+
}
185+
}
186+
162187
@override
163188
void didChange(T? value) {
164189
super.didChange(value);
190+
_informFormForFieldChange(
191+
isSetState: false,
192+
);
165193
widget.onChanged?.call(value);
166194
}
167195

0 commit comments

Comments
 (0)