Represent the relationship without flattening the records.
The parent dataset owns customers, invoices, projects, or another primary entity. The child dataset owns orders, lines, tasks, or events. Each dataset keeps the fields and rules that actually belong to its records.
A master relation constrains child loading from the current parent key. Moving the parent cursor changes the child view, but it does not erase the child dataset’s own editing, validation, paging, or persistence contract.
final customers = FdcDataSet(
fields: customerFields,
adapter: customerAdapter,
);
final orders = FdcDataSet(
fields: orderFields,
adapter: orderAdapter,
masterDataSet: customers,
masterRelation: const [
FdcMasterDetailRelation(
masterField: 'customer_id',
detailField: 'customer_id',
),
],
);
Master-detail DataSets
Configure the parent key, detail key, and lifecycle of the related dataset.
Learn more →PRO PREVIEWIndependent schemas
Keep customer validation separate from order validation and persistence.
Learn more →PRO PREVIEWBuild the screen
Compose related datasets into a practical master-detail workflow.
Learn more →Open the child workflow directly beneath its parent row.
An FdcGridDetailRow is a regular Flutter content surface attached to a stable source-row context. It can show a child grid, form, report, chart, document preview, or application-specific controls without navigating away from the parent list.
The detail grid can use different columns, row height, menus, summaries, and editing rules. Expansion may be single or multiple, content-sized or fixed-height, and controlled by the user or application code.
FdcProGrid(
dataSet: customers,
detailRow: FdcGridDetailRow(
singleExpanded: true,
detailHeight: null,
builder: (context, row) {
return CustomerOrders(
customerId: row.value<int>('customer_id')!,
);
},
),
)
Stable row context
Read values from the expanded source row instead of assuming it is still current.
Learn more →PRO PREVIEWExpansion policy
Control single expansion, row-tap behaviour, sizing, and eligibility.
Learn more →PRO PREVIEWProgrammatic control
Expand, collapse, or close all detail rows through the grid controller.
Learn more →Child operations can affect the parent without merging both models.
Posting or deleting a child record may change the parent’s revenue, count, last activity date, status, or another derived value. Handle that coordination explicitly after the child lifecycle completes, while both datasets remain independently testable.
Remote relationships also need stale-result protection. When the user moves or expands another parent before a child request returns, only the result for the active relationship should become visible.
afterPost: (orders) {
customers.edit();
customers.setFieldValue(
'revenue',
orders.aggregates.sum('total'),
);
customers.post();
},
Lifecycle callbacks
Refresh parent calculations after child post, delete, or reload.
Learn more →PRO PREVIEWFocus management
Keep keyboard and pointer interaction directed to the correct nested surface.
Learn more →PRO PREVIEWRemote relation loading
Load child data on demand while preventing an older response from replacing newer context.
Learn more →Explore the Pro capability in the documentation.
Review the current API and interaction model while Pro distribution is being prepared.