Framework
Version
Enterprise

Erweiterungsanleitung

Beispiele

Möchten Sie direkt zur Implementierung springen? Sehen Sie sich diese Beispiele an

API

Erweiterungs-API

Anleitung zur Erweiterungsfunktion

Erweiterung ist eine Funktion, die es Ihnen ermöglicht, zusätzliche Datenzeilen, die sich auf eine bestimmte Zeile beziehen, anzuzeigen und auszublenden. Dies kann nützlich sein, wenn Sie hierarchische Daten haben und Benutzern ermöglichen möchten, von einer höheren Ebene in die Daten abzutauchen. Oder es kann nützlich sein, um zusätzliche Informationen anzuzeigen, die sich auf eine Zeile beziehen.

Verschiedene Anwendungsfälle für Erweiterungsfunktionen

Es gibt mehrere Anwendungsfälle für Erweiterungsfunktionen in TanStack Table, die im Folgenden besprochen werden.

  1. Erweiterung von Unterzeilen (Kindzeilen, Aggregatzeilen usw.)
  2. Erweiterung benutzerdefinierter UI (Detailfenster, Untertabellen usw.)

Clientseitige Erweiterung aktivieren

Um die clientseitigen Erweiterungsfunktionen zu nutzen, müssen Sie die Funktion `getExpandedRowModel` in Ihren Tabellenoptionen definieren. Diese Funktion ist dafür verantwortlich, das erweiterte Zeilenmodell zurückzugeben.

ts
const table = useReactTable({
  // other options...
  getExpandedRowModel: getExpandedRowModel(),
})
const table = useReactTable({
  // other options...
  getExpandedRowModel: getExpandedRowModel(),
})

Erweiterte Daten können entweder Tabellenzeilen oder beliebige andere Daten enthalten, die Sie anzeigen möchten. In dieser Anleitung wird besprochen, wie beide Fälle behandelt werden.

Tabellenzeilen als erweiterte Daten

Erweiterte Zeilen sind im Wesentlichen Kindzeilen, die dieselbe Spaltenstruktur wie ihre übergeordneten Zeilen erben. Wenn Ihr Datenobjekt bereits diese erweiterten Zeilendaten enthält, können Sie die Funktion getSubRows verwenden, um diese Kindzeilen anzugeben. Wenn Ihr Datenobjekt jedoch nicht die erweiterten Zeilendaten enthält, können sie als benutzerdefinierte erweiterte Daten behandelt werden, die im nächsten Abschnitt behandelt werden.

Wenn Sie beispielsweise ein Datenobjekt wie dieses haben

ts
type Person = {
  id: number
  name: string
  age: number
  children?: Person[] | undefined
}

const data: Person[] =  [
  { id: 1, 
  name: 'John', 
  age: 30, 
  children: [
      { id: 2, name: 'Jane', age: 5 },
      { id: 5, name: 'Jim', age: 10 }
    ] 
  },
  { id: 3,
   name: 'Doe', 
   age: 40, 
    children: [
      { id: 4, name: 'Alice', age: 10 }
    ] 
  },
]
type Person = {
  id: number
  name: string
  age: number
  children?: Person[] | undefined
}

const data: Person[] =  [
  { id: 1, 
  name: 'John', 
  age: 30, 
  children: [
      { id: 2, name: 'Jane', age: 5 },
      { id: 5, name: 'Jim', age: 10 }
    ] 
  },
  { id: 3,
   name: 'Doe', 
   age: 40, 
    children: [
      { id: 4, name: 'Alice', age: 10 }
    ] 
  },
]

Dann können Sie die Funktion `getSubRows` verwenden, um das `children`-Array in jeder Zeile als erweiterte Zeilen zurückzugeben. Die Tabelleninstanz weiß dann, wo sie nach den Unterzeilen jeder Zeile suchen muss.

ts
const table = useReactTable({
  // other options...
  getSubRows: (row) => row.children, // return the children array as sub-rows
  getCoreRowModel: getCoreRowModel(),
  getExpandedRowModel: getExpandedRowModel(),
})
const table = useReactTable({
  // other options...
  getSubRows: (row) => row.children, // return the children array as sub-rows
  getCoreRowModel: getCoreRowModel(),
  getExpandedRowModel: getExpandedRowModel(),
})

Hinweis: Sie können eine komplizierte getSubRows-Funktion haben, aber denken Sie daran, dass sie für jede Zeile und jede Unterzeile ausgeführt wird. Dies kann teuer sein, wenn die Funktion nicht optimiert ist. Asynchrone Funktionen werden nicht unterstützt.

Benutzerdefinierte Erweiterungs-UI

In einigen Fällen möchten Sie möglicherweise zusätzliche Details oder Informationen anzeigen, die möglicherweise Teil Ihres Tabellendatenobjekts sind oder auch nicht, wie z. B. erweiterte Daten für Zeilen. Diese Art von UI für erweiterte Zeilen hat im Laufe der Jahre viele Namen gehabt, darunter "erweiterbare Zeilen", "Detailfenster", "Unterkomponenten" usw.

Standardmäßig gibt die Zeileninstanz-API row.getCanExpand() `false` zurück, es sei denn, sie findet `subRows` in einer Zeile. Dies kann überschrieben werden, indem Ihre eigene Funktion getRowCanExpand in den Optionen der Tabelleninstanz implementiert wird.

ts
//...
const table = useReactTable({
  // other options...
  getRowCanExpand: (row) => true, // Add your logic to determine if a row can be expanded. True means all rows include expanded data
  getCoreRowModel: getCoreRowModel(),
  getExpandedRowModel: getExpandedRowModel(),
})
//...
<tbody>
  {table.getRowModel().rows.map((row) => (
    <React.Fragment key={row.id}>
     {/* Normal row UI */}
      <tr>
        {row.getVisibleCells().map((cell) => (
          <td key={cell.id}>
            <FlexRender
              render={cell.column.columnDef.cell}
              props={cell.getContext()}
            />
          </td>
        ))}
      </tr>
      {/* If the row is expanded, render the expanded UI as a separate row with a single cell that spans the width of the table */}
      {row.getIsExpanded() && (
        <tr>
          <td colSpan={row.getAllCells().length}> // The number of columns you wish to span for the expanded data if it is not a row that shares the same columns as the parent row
            // Your custom UI goes here
          </td>
        </tr>
      )}
    </React.Fragment>
  ))}
</tbody>
//...
//...
const table = useReactTable({
  // other options...
  getRowCanExpand: (row) => true, // Add your logic to determine if a row can be expanded. True means all rows include expanded data
  getCoreRowModel: getCoreRowModel(),
  getExpandedRowModel: getExpandedRowModel(),
})
//...
<tbody>
  {table.getRowModel().rows.map((row) => (
    <React.Fragment key={row.id}>
     {/* Normal row UI */}
      <tr>
        {row.getVisibleCells().map((cell) => (
          <td key={cell.id}>
            <FlexRender
              render={cell.column.columnDef.cell}
              props={cell.getContext()}
            />
          </td>
        ))}
      </tr>
      {/* If the row is expanded, render the expanded UI as a separate row with a single cell that spans the width of the table */}
      {row.getIsExpanded() && (
        <tr>
          <td colSpan={row.getAllCells().length}> // The number of columns you wish to span for the expanded data if it is not a row that shares the same columns as the parent row
            // Your custom UI goes here
          </td>
        </tr>
      )}
    </React.Fragment>
  ))}
</tbody>
//...

Status von erweiterten Zeilen

Wenn Sie den erweiterten Zustand der Zeilen in Ihrer Tabelle steuern müssen, können Sie dies mit dem `expanded`-Status und der Option onExpandedChange tun. Dies ermöglicht es Ihnen, den erweiterten Zustand nach Ihren Anforderungen zu verwalten.

ts
const [expanded, setExpanded] = useState<ExpandedState>({})

const table = useReactTable({
  // other options...
  state: {
    expanded: expanded, // must pass expanded state back to the table
  },
  onExpandedChange: setExpanded
})
const [expanded, setExpanded] = useState<ExpandedState>({})

const table = useReactTable({
  // other options...
  state: {
    expanded: expanded, // must pass expanded state back to the table
  },
  onExpandedChange: setExpanded
})

Der Typ `ExpandedState` ist wie folgt definiert

ts
type ExpandedState = true | Record<string, boolean>
type ExpandedState = true | Record<string, boolean>

Wenn der `ExpandedState` `true` ist, bedeutet dies, dass alle Zeilen erweitert sind. Wenn es sich um einen Record handelt, sind nur die Zeilen mit IDs, die als Schlüssel in dem Record vorhanden sind und deren Wert auf `true` gesetzt ist, erweitert. Wenn beispielsweise der erweiterte Zustand `{ row1: true, row2: false }` ist, bedeutet dies, dass die Zeile mit der ID `row1` erweitert ist und die Zeile mit der ID `row2` nicht erweitert ist. Dieser Status wird von der Tabelle verwendet, um zu bestimmen, welche Zeilen erweitert sind und ihre `subRows` anzeigen sollten, falls vorhanden.

Umschalt-Handler für erweiterte Zeilen

TanStack Table fügt Ihrer Tabelle keinen UI-Handler zum Umschalten für erweiterte Daten hinzu. Sie müssen ihn manuell innerhalb der UI jeder Zeile hinzufügen, damit Benutzer die Zeile erweitern und reduzieren können. Sie können beispielsweise eine Schaltfläche-UI innerhalb der Spaltendefinition hinzufügen.

ts
const columns = [
  {
    accessorKey: 'name',
    header: 'Name',
  },
  {
    accessorKey: 'age',
    header: 'Age',
  },
  {
    header: 'Children',
    cell: ({ row }) => {
      return row.getCanExpand() ?
        <button
          onClick={row.getToggleExpandedHandler()}
          style={{ cursor: 'pointer' }}
        >
        {row.getIsExpanded() ? '👇' : '👉'}
        </button>
       : '';
    },
  },
]
const columns = [
  {
    accessorKey: 'name',
    header: 'Name',
  },
  {
    accessorKey: 'age',
    header: 'Age',
  },
  {
    header: 'Children',
    cell: ({ row }) => {
      return row.getCanExpand() ?
        <button
          onClick={row.getToggleExpandedHandler()}
          style={{ cursor: 'pointer' }}
        >
        {row.getIsExpanded() ? '👇' : '👉'}
        </button>
       : '';
    },
  },
]

Gefilterte erweiterte Zeilen

Standardmäßig beginnt der Filterprozess bei den übergeordneten Zeilen und bewegt sich nach unten. Das bedeutet, wenn eine übergeordnete Zeile vom Filter ausgeschlossen wird, werden auch alle ihre Kindzeilen ausgeschlossen. Sie können dieses Verhalten jedoch ändern, indem Sie die Option filterFromLeafRows verwenden. Wenn diese Option aktiviert ist, beginnt der Filterprozess bei den Blatt- (Kind-) Zeilen und bewegt sich nach oben. Dies stellt sicher, dass eine übergeordnete Zeile in die gefilterten Ergebnisse aufgenommen wird, solange mindestens eine ihrer Kind- oder Enkelzeilen die Filterkriterien erfüllt. Darüber hinaus können Sie steuern, wie tief der Filterprozess in die Kindhierarchie eindringt, indem Sie die Option maxLeafRowFilterDepth verwenden. Diese Option ermöglicht es Ihnen, die maximale Tiefe der Kindzeilen anzugeben, die der Filter berücksichtigen soll.

ts
//...
const table = useReactTable({
  // other options...
  getSubRows: row => row.subRows,
  getCoreRowModel: getCoreRowModel(),
  getFilteredRowModel: getFilteredRowModel(),
  getExpandedRowModel: getExpandedRowModel(),
  filterFromLeafRows: true, // search through the expanded rows
  maxLeafRowFilterDepth: 1, // limit the depth of the expanded rows that are searched
})
//...
const table = useReactTable({
  // other options...
  getSubRows: row => row.subRows,
  getCoreRowModel: getCoreRowModel(),
  getFilteredRowModel: getFilteredRowModel(),
  getExpandedRowModel: getExpandedRowModel(),
  filterFromLeafRows: true, // search through the expanded rows
  maxLeafRowFilterDepth: 1, // limit the depth of the expanded rows that are searched
})

Paginierte erweiterte Zeilen

Standardmäßig werden erweiterte Zeilen zusammen mit dem Rest der Tabelle paginiert (was bedeutet, dass erweiterte Zeilen mehrere Seiten umfassen können). Wenn Sie dieses Verhalten deaktivieren möchten (was bedeutet, dass erweiterte Zeilen immer auf der Seite ihrer Eltern gerendert werden. Dies bedeutet auch, dass mehr Zeilen gerendert werden als die eingestellte Seitengröße), können Sie die Option paginateExpandedRows verwenden.

ts
const table = useReactTable({
  // other options...
  paginateExpandedRows: false,
})
const table = useReactTable({
  // other options...
  paginateExpandedRows: false,
})

Angeheftete erweiterte Zeilen

Das Anheften erweiterter Zeilen funktioniert genauso wie das Anheften regulärer Zeilen. Sie können erweiterte Zeilen oben oder unten in der Tabelle anheften. Weitere Informationen zum Anheften von Zeilen finden Sie in der Anleitung zum Anheften.

Sortierte erweiterte Zeilen

Standardmäßig werden erweiterte Zeilen zusammen mit dem Rest der Tabelle sortiert.

Manuelle Erweiterung (serverseitig)

Wenn Sie die Erweiterung serverseitig durchführen, können Sie die manuelle Zeilenerweiterung aktivieren, indem Sie die Option `manualExpanding` auf `true` setzen. Das bedeutet, dass die Funktion getExpandedRowModel nicht zum Erweitern von Zeilen verwendet wird und Sie die Erweiterung in Ihrem eigenen Datenmodell durchführen müssten.

ts
const table = useReactTable({
  // other options...
  manualExpanding: true,
})
const table = useReactTable({
  // other options...
  manualExpanding: true,
})
Unsere Partner
Code Rabbit
AG Grid
Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.

Bytes abonnieren

Ihre wöchentliche Dosis JavaScript-Nachrichten. Jeden Montag kostenlos an über 100.000 Entwickler geliefert.

Bytes

Kein Spam. Jederzeit kündbar.