Lattice Grid Buy a licence

angular data grid · data router

Angular Grid: Data Router

One feed, split across as many grids as you want by a key on each record, provided as a service scoped to one component. Neither grid below owns its own fetch or its own WebSocket; each just names the route it wants.

Also in: React Vue Svelte

Install and import

npm install @toclocoinc/lattice-grid
# free on localhost; a production domain needs a licence key (see /pricing/)

The files

orders.component.ts

// orders.component.ts
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { createGrid } from '@toclocoinc/lattice-grid';
import '@toclocoinc/lattice-grid/css';
import { createDataRouter } from '@toclocoinc/lattice-grid/modules/data-router';
import { LatticeGridComponent, provideLattice, provideLatticeRouter } from '@toclocoinc/lattice-grid/angular';

const MONEY = { style: 'currency', currency: 'USD', decimals: 0 };
const ORDER_COLUMNS = [
  { field: 'id', title: 'Ref', layout: { width: 110, pin: 'start' } },
  { field: 'region', title: 'Region', filter: { type: 'set' } },
  { field: 'service', title: 'Service', filter: { type: 'set' } },
  { field: 'value', title: 'Value', type: 'number', format: MONEY, total: 'sum' },
];
const RETURN_COLUMNS = ORDER_COLUMNS.map((c) => (c.field === 'value' ? { ...c, title: 'Refund' } : c));

@Component({
  selector: 'app-orders',
  standalone: true,
  imports: [LatticeGridComponent],
  // Scoped to this component: built once on first use, destroyed with it.
  providers: [provideLatticeRouter({ key: 'type', rowKey: 'id' })],
  template:
    '<div style="display:grid;grid-template-columns:1fr 1fr;gap:14px">' +
    '  <lattice-grid route="order" [config]="orderConfig" style="display:block;height:320px"></lattice-grid>' +
    '  <lattice-grid route="return" [config]="returnConfig" style="display:block;height:320px"></lattice-grid>' +
    '</div>',
})
export class OrdersComponent {
  orderConfig = { rowKey: 'id', selection: 'multiple', highlightOnChange: { duration: 500 }, columns: ORDER_COLUMNS, rows: [] };
  returnConfig = { rowKey: 'id', highlightOnChange: { duration: 500 }, columns: RETURN_COLUMNS, rows: [] };
}

bootstrapApplication(OrdersComponent, {
  providers: [provideLattice({ createGrid, createDataRouter })],
});

See it running

Building…
Loading a live grid…

Open this demo's Angular tab →

Working in Angular

The router is a provider, not a field you build. provideLatticeRouter(cfg) goes in the component's own providers array; it is created when the first <lattice-grid route="…"> beneath it attaches, and destroyed with that component, so it lives exactly as long as the screen that owns it.

The config is read once. Rebuilding the router mid-life would drop every attached grid and every row it holds, which is also why it is scoped per-component rather than provided at the root.

Each grid detaches before it is destroyed, in ngOnDestroy, so the router this component provides never ends up holding a reference to a grid that no longer exists.

Related