Export
FlexTreeManager and FlexTree support exporting the tree to Json and List formats.
The following uses the tree below to illustrate how to export a tree.
- Root
- A
- B
- C
toJson
FlexTreeManager, FlexTree, and FlexTreeNode all support the toJson method, which exports the tree to Json format.
toJson(
options?: FlexTreeExportJsonOptions<Fields, KeyFields>
): FlexTreeExportJsonFormat<Fields, KeyFields>
interface FlexTreeExportJsonOptions<
Fields extends Record<string, any> = object,
KeyFields extends CustomTreeKeyFields = DefaultTreeKeyFields,
> {
childrenField?: string
level?: number // Limit the level to export
fields?: (keyof IFlexTreeNode<Fields, KeyFields>)[]
includeKeyFields?: boolean
countField?: string // Attach a descendant-count field
}- Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
options | FlexTreeExportJsonOptions | None | Export options |
options.childrenField | string | 'children' | Child field name |
options.level | number | None | Limit the level to export |
options.fields | (keyof IFlexTreeNode<Fields, KeyFields>)[] | None | Fields to export |
options.includeKeyFields | boolean | false | Whether to export key fields |
options.countField | string | None | Descendant-count field name |
- Return
Returns a JSON object whose child field name defaults to children; it can be customized via the options.childrenField parameter.
type FlexTreeExportJsonFormat<
Fields extends Record<string, any> = object,
KeyFields extends CustomTreeKeyFields = DefaultTreeKeyFields,
TreeNode extends IFlexTreeNode<Fields, KeyFields> = IFlexTreeNode<Fields, KeyFields>,
NodeId = NonUndefined<KeyFields["id"]>[1],
> = TreeNode & {
children?: FlexTreeExportJsonFormat<Fields, KeyFields, TreeNode, NodeId>[];
};- Example
import type { FlexTreeOptions, IFlexTreeNode } from "flextree";
import { FlexTreeManager, FlexTree, FlexTreeVerifyError } from "flextree";
import SqliteAdapter from "flextree-sqlite-adapter";
const sqliteDriver = new SqliteAdapter();
await sqliteDriver.open();
const tree = new FlexTree("tree", {
adapter: sqliteDriver,
});
await tree.load();
tree.toJson();The output is as follows:
{
"id": 1,
"name": "root",
"children": [
{
"id": 2,
"name": "A",
"children": [
{ "id": 3, "name": "A1" },
{ "id": 4, "name": "A2" },
{ "id": 5, "name": "A3" }
]
},
{
"id": 6,
"name": "B",
"children": [
{ "id": 7, "name": "B1" },
{ "id": 8, "name": "B2" },
{ "id": 9, "name": "B3" }
]
},
{
"id": 10,
"name": "C",
"children": [
{ "id": 11, "name": "C1" },
{ "id": 12, "name": "C2" },
{ "id": 13, "name": "C3" }
]
}
]
}Notes
- The
toJsonmethod exports the tree toJsonformat; you can limit the exported level via theoptions.levelparameter. - The
toJsonmethod can be called onFlexTreeandFlexTreeNode. - You can specify the exported fields via the
options.fieldsparameter. - By default the
leftValueandrightValuefields are not exported; useoptions.includeKeyFieldsto specify whether to export key fields. - You can specify the child field name via the
options.childrenFieldparameter.
- The
countField Descendant Count
When options.countField is specified, each node gets an extra field holding its descendant count (0 for leaves):
await manager.toJson({ countField: "count" })
// { "id": 1, "name": "root", "count": 12, "children": [
// { "id": 2, "name": "A", "count": 3, "children": [...] },
// ...
// ] }- The count is computed as
(rightValue - leftValue - 1) / 2and is always the full descendant count — unaffected byleveltruncation (withlevel: 2, the root's count still includes deeper descendants) countFieldhas the same standing asid: it is attached even whenfieldsfiltering is specified, independent ofincludeKeyFields- Conflicting with an existing node field throws a
FlexTreeError - With the recycle bin enabled the count uses the visible scope: by default it excludes recycled nodes (consistent with the exported content); with
includeRecyclebin: trueit is the full physical count
toList
FlexTreeManager, FlexTree, and FlexTreeNode all support the toList method, which exports the tree to a list node array with a pid field.
toList(
options?: FlexTreeExportListOptions<Fields, KeyFields>
): FlexTreeExportListFormat<Fields, KeyFields>
interface FlexTreeExportListOptions<
Fields extends Record<string, any> = object,
KeyFields extends CustomTreeKeyFields = DefaultTreeKeyFields,
> {
pidField?: string
level?: number // Limit the level to export
fields?: (keyof IFlexTreeNode<Fields, KeyFields>)[]
includeKeyFields?: boolean
countField?: string // Attach a descendant-count field
}- Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
options | FlexTreeExportListOptions | None | Export options |
options.pidField | string | 'pid' | Parent field name |
options.level | number | None | Limit the level to export |
options.fields | (keyof IFlexTreeNode<Fields, KeyFields>)[] | None | Fields to export |
options.includeKeyFields | boolean | false | Whether to export key fields |
options.countField | string | None | Descendant-count field name |
- Return
Returns a list node array whose parent field name defaults to pid; it can be customized via the options.pidField parameter.
export type FlexTreeExportListFormat<
Fields extends Record<string, any> = object,
KeyFields extends CustomTreeKeyFields = DefaultTreeKeyFields,
TreeNode extends IFlexTreeNode<Fields, KeyFields> = IFlexTreeNode<Fields, KeyFields>,
NodeId = NonUndefined<KeyFields["id"]>[1],
OPTIONS extends FlexTreeExportListOptions<Fields, KeyFields> = FlexTreeExportListOptions<
Fields,
KeyFields
>,
> = ((OPTIONS["fields"] extends string[]
? Extract<TreeNode, OPTIONS["fields"][number]>
: TreeNode) & { [P in OPTIONS["pidField"] & string]: NodeId })[];- Example
import type { FlexTreeOptions, IFlexTreeNode } from "flextree";
import { FlexTreeManager, FlexTree, FlexTreeVerifyError } from "flextree";
import SqliteAdapter from "flextree-sqlite-adapter";
const sqliteDriver = new SqliteAdapter();
await sqliteDriver.open();
const tree = new FlexTree("tree", {
adapter: sqliteDriver,
});
await tree.load();
tree.toList();The output is as follows:
[
{ "id": 1, "name": "root", "pid": 0 },
{ "id": 2, "name": "A", "pid": 1 },
{ "id": 3, "name": "A1", "pid": 2 },
{ "id": 4, "name": "A2", "pid": 2 },
{ "id": 5, "name": "A3", "pid": 2 },
{ "id": 6, "name": "B", "pid": 1 },
{ "id": 7, "name": "B1", "pid": 6 },
{ "id": 8, "name": "B2", "pid": 6 },
{ "id": 9, "name": "B3", "pid": 6 },
{ "id": 10, "name": "C", "pid": 1 },
{ "id": 11, "name": "C1", "pid": 10 },
{ "id": 12, "name": "C2", "pid": 10 },
{ "id": 13, "name": "C3", "pid": 10 }
]Note
Both toList and toJson support a level parameter to limit the exported level. They can be called on FlexTree and FlexTreeNode. The semantics of countField are described in countField Descendant Count above.
getTree
FlexTreeManager provides the getTree method, which builds an in-memory FlexTree object based on the current manager, so that you can use the rich API provided by FlexTree (such as getByPath, find, toJson, toList, etc.).
getTree(options?: FlexTreeOptions): FlexTree<Fields, KeyFields>- Example
const tree = manager.getTree()
await tree.load() // FlexTree must be loaded manually before it can be accessed
tree.getByPath('/A/A-1')Note
FlexTreeManager also provides two async convenience methods, toJson and toList, which automatically build and load the tree via getTree before exporting:
await manager.toJson()
await manager.toList()