developer guide
Using Lattice Grid with Angular
A standalone component over the same grid every other page runs. You hand the adapter Angular and createGrid; it hands you a component.
Install
The grid and its adapters are one package. The Angular adapter is a separate entry point, so a bundle that never imports it never carries it.
npm i @toclocoinc/lattice-grid
The adapter is a factory
You call createLatticeGrid and hand it your copy of Angular's core namespace and the
grid's createGrid, and it returns a standalone component bound to them.
import * as ng from '@angular/core';
import { createGrid } from '@toclocoinc/lattice-grid';
import '@toclocoinc/lattice-grid/css';
import createLatticeGrid from '@toclocoinc/lattice-grid/modules/angular';
// Build the components once. The adapter takes your Angular and your grid.
const { LatticeGridComponent } = createLatticeGrid({ ng, createGrid });
The adapter takes no dependency on Angular and carries no second copy of the grid: both are passed in, so there is exactly one Angular and one grid on the page, the versions you installed, and the adapter cannot drift out of step with either. It is a small piece of glue rather than a bundled framework.
One input carries the configuration
Add LatticeGridComponent to a standalone component's imports and drop
<lattice-grid> in the template. Its config input is the grid's own
configuration, columns and rows and everything else. Change the object and the adapter pushes the
change through the grid's public API rather than rebuilding it, so scroll position, selection and
open editors survive. Sort, filters, the quick filter and the selected keys each have their own
input as well.
@Component({
selector: 'app-circuits',
standalone: true,
imports: [LatticeGridComponent],
template: '<lattice-grid [config]="grid" style="display:block;height:520px"></lattice-grid>',
})
export class CircuitsComponent {
grid = {
rowKey: 'id',
columns: [
{ field: 'circuit', title: 'Circuit', layout: { pin: 'start', width: 190 } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'charge', title: 'Monthly charge', type: 'number',
format: { style: 'currency', currency: 'GBP' }, total: 'sum' },
],
rows: [/* your rows */],
};
}
Events are outputs
Every grid event arrives as an Angular output, named with dashes: cell:changed
becomes (cell-changed). Bind the ones you need and leave the rest.
@Component({
selector: 'app-circuits',
standalone: true,
imports: [LatticeGridComponent],
template: '<lattice-grid [config]="grid" (cell-changed)="onCellChanged($event)"></lattice-grid>',
})
export class CircuitsComponent {
grid = { rowKey: 'id', columns, rows };
onCellChanged(e: any) { console.log('changed', e); }
}
Reaching the grid instance
For anything the inputs do not cover, an export, a programmatic filter, a scroll, the component
exposes the live grid on a grid getter. Read it with @ViewChild. That is
the same object the docs describe everywhere else; the adapter adds nothing to it and hides
nothing from it.
import { Component, ViewChild, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-circuits',
standalone: true,
imports: [LatticeGridComponent],
template: '<lattice-grid [config]="grid"></lattice-grid>',
})
export class CircuitsComponent implements AfterViewInit {
@ViewChild(LatticeGridComponent) gridRef!: LatticeGridComponent;
grid = { rowKey: 'id', columns, rows };
ngAfterViewInit() {
// gridRef.grid is the real grid instance: the whole public API.
this.gridRef.grid.export.csv({ download: true });
}
}
Cleanup on destroy
The adapter destroys the underlying grid when the component is destroyed, releasing its listeners and observers, so there is nothing to clean up by hand.
TypeScript
Type declarations travel with the package, so column and config types are picked up without any tsconfig work. Type your columns and the editor checks them against the grid's own definitions.
import type { GridColumn } from '@toclocoinc/lattice-grid';
const columns: GridColumn[] = [
{ field: 'charge', title: 'Charge', type: 'number', total: 'sum' },
];
One grid per page
Use the Angular adapter or the web component, not both on one page. The web component bundle carries its own copy of the grid, and two copies keep separate registries: a renderer registered through one is invisible to the other. Pick one entry point per page and stay on it.
See also the Angular data grid overview, and the rest of the developer guide.