DataGrid expanded state
Track expanded details by a stable record key so they follow records through sorting, paging and data refreshes.
Control expanded rows
Provide detailRowKey and bind expandedDetailKeys to your application's state. Handle expandedDetailKeysChange to receive disclosure changes. The following example demonstrates two initially expanded records among 24 rows. Sort a column, change pages or reload the records to check that expansion follows their IDs.
Expanded keys: 1041, 1044
Delivery window 9:00–11:00. Use the receiving entrance. | ||||
Delivery window 12:00–14:00. Use the receiving entrance. | ||||
<ngb-datagrid [data]="orders" [columns]="columns"
[detailRowKey]="orderKey" [expandedDetailKeys]="expandedKeys()"
(expandedDetailKeysChange)="expandedKeys.set($event)">
<ng-template ngbRowDetail let-order><p>{{ order.note }}</p></ng-template>
</ngb-datagrid>
readonly orderKey = (order: Order): number => order.id;
readonly expandedKeys = signal<readonly NgbDataGridDetailKey[]>([1041, 1044]);
// Import signal from @angular/core and NgbDataGridDetailKey from the library.
// Collapse all: this.expandedKeys.set([]);
Choose stable keys
Use a unique, nonempty string or finite number, such as a record ID. Keep the selector pure. Matching keys retain expansion across pages and data refreshes; invalid keys cannot expand.
Events and persistence
Replace key arrays immutably. User actions emit expandedDetailKeysChange; detailChange reports current-page row transitions. Input updates and off-page key removal emit no row event.
Your app owns loading, storage and obsolete-key cleanup. Saved views and Undo/Redo exclude expansion.
Compatibility and keyboard support
Without detailRowKey, expansion follows page indexes. expandRow(index) and collapseRow(index) always take page indexes. singleExpand clears other keys when opening a row, but leaves supplied initial keys unchanged.
Use Tab, then Enter or Space on a disclosure. See master-detail overview for nested-grid shortcuts and limitations.