Skip to content

GridLazyForm

Directive that provides lazy FormGroup creation for grid editing.

Unlike GridFormArray which creates all FormGroups upfront, this directive creates FormGroups on-demand only when a row enters edit mode. This provides much better performance for large datasets while still enabling full Angular Reactive Forms integration.

  • Performance: Only creates FormGroups for rows being edited (20-100x fewer controls)
  • Same DX: Editors still receive control in their context for validation
  • Memory efficient: FormGroups are cleaned up when rows exit edit mode
import { Component, inject, signal } from '@angular/core';
import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { Grid, GridLazyForm, TbwEditor } from '@toolbox-web/grid-angular';
@Component({
imports: [Grid, GridLazyForm, TbwEditor, ReactiveFormsModule],
template: `
<tbw-grid
[rows]="employees()"
[lazyForm]="createRowForm"
[gridConfig]="config">
<tbw-grid-column field="firstName">
<input *tbwEditor="let _; control as ctrl"
[formControl]="ctrl"
[class.is-invalid]="ctrl?.invalid && ctrl?.touched" />
</tbw-grid-column>
</tbw-grid>
`
})
export class MyComponent {
private fb = inject(FormBuilder);
employees = signal(generateEmployees(1000));
// Factory called when editing starts - only include editable fields!
createRowForm = (row: Employee): FormGroup => this.fb.group({
firstName: [row.firstName, Validators.required],
lastName: [row.lastName, Validators.minLength(2)],
salary: [row.salary, [Validators.required, Validators.min(0)]],
});
gridConfig = { columns: [...] };
}
  1. Rows come from [rows] input (plain data array)
  2. When a cell enters edit mode, the FormGroup is created lazily
  3. Editors receive the FormControl in their template context
  4. On commit, FormGroup values are synced back to the row
  5. FormGroup is cleaned up when the row exits edit mode (configurable)
RowsGridFormArray (20 fields)GridLazyForm
1002,000 controls~20 controls
50010,000 controls~20 controls
100020,000 controls~20 controls
PropertyTypeDescription
lazyFormInputSignal<LazyFormFactory<TRow>>Factory function to create a FormGroup for a row. Called lazily when the row first enters edit mode.
syncValidationInputSignal<boolean>Whether to automatically sync Angular validation state to grid’s visual invalid styling.
keepFormGroupsInputSignal<boolean>Whether to keep FormGroups cached after a row exits edit mode.
rowFormChangeOutputEmitterRef<RowFormChangeEvent<TRow>>Emitted when a row’s form values change. Useful for auto-save, validation display, or syncing to external state.
createRowForm = (row: Employee): FormGroup => this.fb.group({
firstName: [row.firstName, Validators.required],
lastName: [row.lastName],
salary: [row.salary, [Validators.min(0)]],
});

Whether to automatically sync Angular validation state to grid’s visual invalid styling.

When enabled:

  • After a cell commit, if the FormControl is invalid, the cell is marked with setInvalid()
  • When a FormControl becomes valid, clearInvalid() is called
  • On row-commit, if the row’s FormGroup has invalid controls, the commit is prevented

Default: true


Whether to keep FormGroups cached after a row exits edit mode.

  • true: FormGroups are kept, preserving dirty/touched state across edit sessions
  • false: FormGroups are disposed when the row exits edit mode (default)

Default: false


A callback method that is invoked immediately after the default change detector has checked the directive’s data-bound properties for the first time, and before any of the view or content children have been checked. It is invoked only once when the directive is instantiated.

ngOnInit(): void

A callback method that performs custom clean-up, invoked immediately before a directive, pipe, or service instance is destroyed.

ngOnDestroy(): void

Gets the FormGroup for a row, if it exists. Unlike the context methods, this does NOT create a FormGroup lazily.

getFormGroup(rowIndex: number): FormGroup<any> | undefined
NameTypeDescription
rowIndexnumberThe row index

FormGroup<any> | undefined - The FormGroup or undefined


Gets all cached FormGroups. Useful for bulk validation or inspection.

getAllFormGroups(): ReadonlyMap<TRow, FormGroup<any>>

ReadonlyMap<TRow, FormGroup<any>> - Map of row objects to their FormGroups


Clears all cached FormGroups. Useful when the underlying data changes significantly.

clearAllFormGroups(): void

Validates all currently cached FormGroups.

validateAll(): boolean

boolean - true if all FormGroups are valid, false otherwise


AI assistants: For complete API documentation, implementation guides, and code examples for this library, see https://raw.githubusercontent.com/OysteinAmundsen/toolbox/main/llms-full.txt