Skip to content

Commit

Permalink
feat(angular-table): added injector optional parameter for more flexi…
Browse files Browse the repository at this point in the history
…bility (#5525)

* feat(angular-table): improve adapter implementation (#5524)

* Added optional injector for more flexibility
* Replace runInInjectionContext with injector in effect

* feat(angular-table): Added proxifyTable back

* feat(angular-table): adding back notifier signal for table changed

* feat(angular-table): Improve logic in setting table options
*set table options inside computed before returning the table instance
*remove redundant signals and effect
*remove injector as it no longer required
*update Grouping example to show how to pass signal when creating table
  • Loading branch information
merto20 authored May 7, 2024
1 parent ca9491c commit 7af1fd6
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 78 deletions.
11 changes: 6 additions & 5 deletions examples/angular/grouping/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ import {
ChangeDetectionStrategy,
Component,
computed,
effect,
signal,
} from '@angular/core'
import {
createAngularTable,
FlexRenderDirective,
GroupingState,
Updater,
createAngularTable,
getCoreRowModel,
getExpandedRowModel,
getFilteredRowModel,
getGroupedRowModel,
getPaginationRowModel,
GroupingState,
Updater,
} from '@tanstack/angular-table'
import { columns } from './columns'
import { makeData } from './makeData'
Expand All @@ -34,7 +33,7 @@ export class AppComponent {

stringifiedGrouping = computed(() => JSON.stringify(this.grouping(), null, 2))

table = createAngularTable(() => ({
tableOptions = computed(() => ({
data: this.data(),
columns: columns,
state: {
Expand All @@ -55,6 +54,8 @@ export class AppComponent {
debugTable: true,
}))

table = createAngularTable(this.tableOptions)

onPageInputChange(event: any): void {
const page = event.target.value ? Number(event.target.value) - 1 : 0
this.table.setPageIndex(page)
Expand Down
122 changes: 49 additions & 73 deletions packages/angular-table/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,96 +1,72 @@
import { computed, signal } from '@angular/core'
import {
computed,
effect,
inject,
Injector,
runInInjectionContext,
type Signal,
signal,
untracked,
} from '@angular/core'
import {
createTable,
RowData,
type Table,
TableOptions,
TableOptionsResolved,
TableState,
createTable,
type Table,
} from '@tanstack/table-core'
import { proxifyTable } from './proxy'
import { lazyInit } from './lazy-signal-initializer'
import { proxifyTable } from './proxy'

export * from '@tanstack/table-core'

export {
FlexRenderDirective,
FlexRenderComponent,
FlexRenderDirective,
injectFlexRenderContext,
} from './flex-render'

export function createAngularTable<TData extends RowData>(
options: () => TableOptions<TData>
): Table<TData> & Signal<Table<TData>> {
const injector = inject(Injector)
): Table<TData> {
return lazyInit(() => {
const resolvedOptions = {
state: {},
onStateChange: () => {},
renderFallbackValue: null,
...options(),
}

return lazyInit(() =>
runInInjectionContext(injector, () => {
const resolvedOptionsSignal = computed<TableOptionsResolved<TData>>(
() => {
return {
state: {},
onStateChange: () => {},
renderFallbackValue: null,
...options(),
}
}
)
const table = createTable(resolvedOptions)

const notifier = signal([], { equal: () => false })
const table = createTable(untracked(resolvedOptionsSignal))
const state = signal(table.initialState)
// By default, manage table state here using the table's initial state
const state = signal<TableState>(table.initialState)

function updateOptions() {
const tableState = untracked(state)
const resolvedOptions = untracked(resolvedOptionsSignal)
untracked(() => {
table.setOptions(prev => ({
...prev,
...resolvedOptions,
state: { ...tableState, ...resolvedOptions.state },
onStateChange: updater => {
const value =
updater instanceof Function ? updater(tableState) : updater
state.set(value)
resolvedOptions.onStateChange?.(updater)
},
}))
})
// Compose table options using computed.
// This is to allow `tableSignal` to listen and set table option
const updatedOptions = computed<TableOptionsResolved<TData>>(() => {
// listen to table state changed
const tableState = state()
// listen to input options changed
const tableOptions = options()
return {
...table.options,
...resolvedOptions,
...tableOptions,
state: { ...tableState, ...tableOptions.state },
onStateChange: updater => {
const value =
updater instanceof Function ? updater(tableState) : updater
state.set(value)
resolvedOptions.onStateChange?.(updater)
},
}
})

updateOptions()

let firstRender = true
effect(() => {
void [state(), resolvedOptionsSignal()]
if (firstRender) {
return (firstRender = false)
}
untracked(() => {
updateOptions()
notifier.set([])
})
})

const tableSignal = computed(
() => {
notifier()
return table
},
{
equal: () => false,
}
)
// convert table instance to signal for proxify to listen to any table state and options changes
const tableSignal = computed(
() => {
table.setOptions(updatedOptions())
return table
},
{
equal: () => false,
}
)

return proxifyTable(tableSignal)
})
)
// proxify Table instance to provide ability for consumer to listen to any table state changes
return proxifyTable(tableSignal)
})
}

0 comments on commit 7af1fd6

Please sign in to comment.