Subform patterns
Detach a section or switch its validation off? Swap one section for another? The trade-offs, and where the example app shows each.
Detach, or switch validation off?
A section that is visible but not applicable — invoice details behind an unchecked "I need an invoice" switch — is
better kept attached with setValidationEnabled(false):
- its errors are cleared and its fields leave
canSubmit,validating,hasFailedValidationandvalidationErrors; - its
validate()returnstruewithout running; - everything else —
resetAll,markReadOnly,clearErrors, disposal — still reaches it; - switching back on re-runs the sync validators at once, and the values are still there.
Detach with removeSubform when the section genuinely leaves the screen and its values should not take part in
anything. A detached subform is still owned — and disposed — by the parent, and can be re-attached later.
CheckoutFormController() {
registerFields([email, needsInvoice]);
addSubform(invoice);
addRelation(needsInvoice, (on) => on, invoice.setValidationEnabled);
invoice.setValidationEnabled(needsInvoice.fieldValue); // relations fire on change only
}Swapping one section for another
A type selector that swaps the active section — a person or a company — is removeSubform of one and
addSubform of the other, reacting to the selector field with addRelation. Only the attached section takes part in
validation; the detached one keeps its values in case the user switches back, and both are disposed with the parent.
addRelation(type, (t) => t, (t) {
if (t == CustomerType.company) {
removeSubform(person);
addSubform(company);
} else {
removeSubform(company);
addSubform(person);
}
});The example app's Complex Form screen is this pattern; Delivery List Form is the dynamic list; Step Form is the wizard with a conditional step. See the example app.
Things that throw
addSubform and removeSubform throw a descriptive StateError when called on a disposed form, and addSubform
also when handed a disposed subform. A disposed controller cannot be reused — build a fresh one per appearance, or keep
the section attached and switch it off. Lifecycle and ownership has the full table.