createViewModel
Table#createViewModel derives the view model that is applied onto markup. It is called on the table instance with Column instances, and returns a TableViewModel.
Usage
Table#createViewModel: (columns, options) => TableViewModel
columns is an array of Column instances returned from Table#createColumns.
options is an optional configuration object to configure the view model.
const table = createTable(data)
const columns = table.createColumns(...)
const vm = table.createViewModel(columns)
// vm.current.headerRows, vm.current.pageRows, vm.current.tableAttrs, ...
// vm.pluginStatesconst table = createTable(data)
const columns = table.createColumns(...)
const vm = table.createViewModel(columns)
// vm.current.headerRows, vm.current.pageRows, vm.current.tableAttrs, ...
// vm.pluginStatesThe view model is built from $derived values. Create it where those can live for as long as the view model is used:
- in a component’s
<script>(the usual place), - at the top level of a
.svelte.ts/.svelte.jsmodule, - in a
loadfunction or a test.
Do not create it inside an $effect or $effect.root that is torn down before you stop using the view model: its derivations would stop updating (Svelte warns derived_inert).
Plain reads of vm.current.* work anywhere, including outside components and during server rendering. To observe changes outside a component (in a test, for example), read inside an $effect created under $effect.root:
const vm = table.createViewModel(columns)
console.log(vm.current.rows.length) // a plain read, no effect needed
const cleanup = $effect.root(() => {
$effect(() => {
console.log('rows now', vm.current.rows.length)
})
})
// ...
cleanup()const vm = table.createViewModel(columns)
console.log(vm.current.rows.length) // a plain read, no effect needed
const cleanup = $effect.root(() => {
$effect(() => {
console.log('rows now', vm.current.rows.length)
})
})
// ...
cleanup()options.rowDataId?: (item, index) => string
Defines a custom dataId for each row.
index of the first sub-row is 0.Defaults to the item index.
options.reuseKey?: string
Opts into reusing the previous view model instead of building a new one. Building a view model instantiates every plugin, so a component that rebuilds on each reactive pass — a derived column array with a new identity but the same columns in it — otherwise loses plugin state such as the current page index or sort order.
const columns = $derived(table.createColumns(...));
const viewModel = $derived(table.createViewModel(columns, { reuseKey: 'main' }));const columns = $derived(table.createColumns(...));
const viewModel = $derived(table.createViewModel(columns, { reuseKey: 'main' }));reuseKey works the same way as in 6.x. The view model is reused when the key, the column ids and rowDataId all match the previous call. A different key, changed columns, or omitting reuseKey builds fresh.
Only the most recently built view model is kept, so the key identifies the current table rather than naming one of several — alternating between two keys rebuilds on every pass. The cache also lives on the Table, so reuse only helps when the createTable call itself is stable and only the columns are derived.