解释
在文档中,(如果不是标准的话) 具有内容或数据的层次结构是非常普遍的:父页面,子页面.
如果您使用的是降价文件或 SSG,则可以使用文件和文件夹轻松创建内容层次结构。 如果您的内容在数据库中,您可以创建具有递归 O2M 关系的嵌套项目的层次结构,这是本节的重点。
在 Directus 中,有一个名为 Tree View 的特殊 O2M 别名字段,可以更轻松地创建和管理此类递归关系。
对于这个秘籍,我们将使用树视图为文档构建一个简单的内容层次结构:
App Overview
Configuration
Flows
Data Model
Collections
Fields
以下是即将发生的事情的大纲:
- 使用树视图在名为“docs”的集合中创建递归关系。
- 使用该递归关系将
parent
<->child
项添加到集合中。 - 授予 public 角色对
docs
的读取权限,以便用户可以访问它们。
最后,在 Final Tips 中,我们将指出您可以采取的一些额外步骤,以使您的内容层次结构更易于在前端使用。
The Recipe
要求
您需要熟悉 权限。
- Create a collection and add fields as follows:
docs
- id
- title (a STRING input field)
- parent_id (an integer input field)
- children (a Tree View O2M alias field, configured with docs.parent_id as the foreign key and the O2M Interface)
- body (optional: a text input field with a Markdown interface)
- 为
docs
集合配置公共角色 读取权限。 - 根据需要在
docs
集合上创建嵌套项:
- 可选:手动排序项目 到所需的顺序。
最后的提示
现在您的嵌套内容已创建,您需要在前端访问和使用它。 这里有两个要点需要考虑。
获取嵌套数据
对 get items 的基本 api 调用,例如 /items/docs/
,返回平面数据:
::details 切换打开以查看平面数据。
{
"data": [
{
"id": 1,
"title": "App Overview",
"parent_id": null,
"body": "# App Overview\n\nGeneral info about the app.",
"sort": 1,
"children": []
},
{
"id": 2,
"title": "Config Overview",
"parent_id": null,
"body": "# Config Overview\n\nThere are many config options available",
"sort": 2,
"children": [3]
},
{
"id": 3,
"title": "Data Model",
"parent_id": 2,
"body": "# How the Data Model Works\n\n",
"sort": 3,
"children": [4, 5]
},
{
"id": 4,
"title": "Fields",
"parent_id": 3,
"body": "# How Fields Work",
"sort": 4,
"children": []
},
{
"id": 5,
"title": "Collections",
"parent_id": 3,
"body": "# Collections\n\nThey're data tables.",
"sort": 5,
"children": []
}
]
}
:: 要解决此问题,您_可以_编写一个算法来遍历数据数组中的每个项目并将其重新嵌套在前端。 但这可能会占用一些资源,具体取决于您收藏的数据。 或者,我们可以在 Directus API 调用上添加 查询参数 来为我们嵌套它。 在这种情况下,我们可以像这样进行 api 调用:
/items/docs?
filter[parent_id][_null]=true
&fields=id,title,body,sort,
children.id,children.body,children.title,children.sort,
children.children.id,children.children.title,children.children.body,children.children.sort, children.children.children
它将返回正确嵌套的数据,如下所示:
::details 切换打开以查看嵌套数据
{
"data": [
{
"id": 1,
"name": "App Overview",
"body": "# App Overview\n\nGeneral info about the app.",
"sort": 1,
"nest": []
},
{
"id": 2,
"name": "Config Overview",
"body": "# Config Overview\n\nMany config options available",
"sort": 2,
"nest": [
{
"id": 3,
"body": "# How the Data Model Works",
"name": "Data Model",
"sort": 3,
"nest": [
{
"id": 4,
"name": "Fields",
"body": "# How Fields Work",
"sort": 4,
"nest": []
},
{
"id": 5,
"name": "Collections",
"body": "# Collections\n\nThey're data tables.",
"sort": 5,
"nest": []
}
]
}
]
}
]
}
::
在上面的调用中,filter[parent_id][_null]=true
查询参数服务于第一级的 filter 非父母。 fields 查询参数让我们提取特定字段,包括嵌套关系字段。 这种类型的查询需要注意两个关键事项:
- We know our content hierarchy was three levels deep. 您还需要了解 (并说明) 内容层次结构的深度,并相应地进行 api 调用。
- 未添加
parent_id
外键字段,因为它会将父项数据重新嵌套在其自己的子项下,这是重复且无用的。
创建相对路径
嵌套内容本身很好,但如果我们可以为每个项目创建一个路径,以便在前端导航中进行路由,那将会很有帮助。 为此,您可以使用 flows 动态创建路径。 这是一种通用方法:
- 向 docs 集合添加一个 path 字段并对其进行配置,以便在项目详细信息页面上关闭编辑。
- 配置流 带有一个“事件钩子”触发器,它在“docs”集合的“items.create”和“items.update”上运行 .
- 向流程添加操作以读取正在创建或更新的项目的父路径,附加项目的标题,将新路径写入当前项目的“路径”字段值,然后更新其子项的路径 (如果它有 任何孩子)。
在这个秘籍中,为了一个清晰的视觉示例,我们直接在 docs 集合上创建了一个 body 字段。 但是,您可能会发现将降价内容保存在另一个相关链接的集合中对用户更友好,然后只需使用树视图来存储路径和/或跟踪内容层次结构。