我正在通过满足的API处理数据,并且正在尝试建立我正在构建的网站的结构。我正在使用GraphQL API并获得满足页面,但是由于限制速率,在获得参考和层次结构方面,我无法对我的查询进行深度深度。
这使我在查询“页面”内容类型并获取每个页面并获取其父页面ID,只有一个级别。理论是,如果我为每个页面执行此操作,我可以通过在构建过程中运行一些JS来递归构建页面结构(我正在使用高架来构建网站)。
我需要一个函数来生成一个面包屑阵列,理想情况下,我会给该功能一个页面的ID,它将跟踪数据,从而为我提供父母的详细信息,父母的父母,依此类推,直到没有更多的父母为止。
我有以下代码,目前分为两个函数(尽管不确定这是最好的方法!)
/**
* This takes an ID and finds it within the contentfulPages array (the result
* of the GraphQL query to Contentful)
* It returns an object containing the page's ID, slug (for the URL), title
* (for the readable text) and the parentPageId so we can use that to get the
* same details for the parent page
*/
function getParentPage(pageId) {
const { id, slug, title, parentPageId } = contentfulPages.find(
(page) => page.id === pageId
);
return { id, slug, title, parentPageId };
}
/**
* This takes an ID and passes it to getParentPage to get the first parentPage
* details. If there is another parent page, it calls itself with the newly
* found parent page and pushes that object to the breadcrumbArray. Because it
* returns the breadcrumb array, each iteration is a more deeply nested array
* as opposed to an object at the same level
*/
function getBreadcrumb(pageId) {
let breadcrumbArray = [];
const { id, slug, title, parentPageId } = getParentPage(pageId);
breadcrumbArray.push({ id, slug, title, parentPageId });
if (parentPageId) {
breadcrumbArray.push(getBreadcrumb(parentPageId));
}
return breadcrumbArray;
}
我明白了为什么它在做它在做什么,但是我不知道如何修复它 - 我想要最终结果是一系列平坦的对象,但是递归功能引起了我的问题,因为我认为它必须返回某些东西,但我不确定该怎么做!
一个三层深页的一个例子是:
// Expected:
[
{
id: 'page-3',
slug: 'courses',
title: 'Courses',
parentPageId: 'page-2'
},
{
id: 'page-2',
slug: 'training',
title: 'Training',
parentPageId: 'page-1'
},
{
id: 'page-1',
slug: 'services',
title: 'Services',
parentPageId: false
},
]
// Actual:
[
{
id: 'page-3',
slug: 'courses',
title: 'Courses',
parentPageId: 'page-2'
},
[
{
id: 'page-2',
slug: 'training',
title: 'Training',
parentPageId: 'page-1'
},
[
{
id: 'page-1',
slug: 'services',
title: 'Services',
parentPageId: false
},
]
]
]
非常感谢您的帮助!
I'm working with data via the Contentful API and I'm trying to build up a structure of the website I'm building. I'm using the GraphQL API and getting Contentful pages, but, due to rate-limiting, I can't go super deep with my query when it comes to getting references and hierarchical structure.
This has left me querying my "pages" content type and getting each page and getting its parent page ID, just one level up. The theory being that if I do this for every page, I can build up the page structure recursively by running some JS during the build (I'm using Eleventy to build the site).
I need a function to generate me a breadcrumbs array, ideally I'd give the function a single page's ID and it would track through the data getting me the details of the parent, the parent's parent and so on until there are no more parents.
I've got the following code, split into two functions at the moment (although not sure if that's the best approach!)
/**
* This takes an ID and finds it within the contentfulPages array (the result
* of the GraphQL query to Contentful)
* It returns an object containing the page's ID, slug (for the URL), title
* (for the readable text) and the parentPageId so we can use that to get the
* same details for the parent page
*/
function getParentPage(pageId) {
const { id, slug, title, parentPageId } = contentfulPages.find(
(page) => page.id === pageId
);
return { id, slug, title, parentPageId };
}
/**
* This takes an ID and passes it to getParentPage to get the first parentPage
* details. If there is another parent page, it calls itself with the newly
* found parent page and pushes that object to the breadcrumbArray. Because it
* returns the breadcrumb array, each iteration is a more deeply nested array
* as opposed to an object at the same level
*/
function getBreadcrumb(pageId) {
let breadcrumbArray = [];
const { id, slug, title, parentPageId } = getParentPage(pageId);
breadcrumbArray.push({ id, slug, title, parentPageId });
if (parentPageId) {
breadcrumbArray.push(getBreadcrumb(parentPageId));
}
return breadcrumbArray;
}
I can see why it's doing what it's doing, but I don't know how to fix it - I want the end result to be a flat array of objects, but the recursive function is causing me problems I think, because I think it has to return something, but I'm not sure how to do that!
An example for a three-levels deep page is this:
// Expected:
[
{
id: 'page-3',
slug: 'courses',
title: 'Courses',
parentPageId: 'page-2'
},
{
id: 'page-2',
slug: 'training',
title: 'Training',
parentPageId: 'page-1'
},
{
id: 'page-1',
slug: 'services',
title: 'Services',
parentPageId: false
},
]
// Actual:
[
{
id: 'page-3',
slug: 'courses',
title: 'Courses',
parentPageId: 'page-2'
},
[
{
id: 'page-2',
slug: 'training',
title: 'Training',
parentPageId: 'page-1'
},
[
{
id: 'page-1',
slug: 'services',
title: 'Services',
parentPageId: false
},
]
]
]
Assistance would be much appreciated!
发布评论
评论(2)
您可以使用 getBreadcrumb 推入结果,而是可以从返回数组中推动单个数组元素-us/docs/web/javascript/referent/operators/spread_syntax“ rel =“ nofollow noreferrer”> vrize语法(
...
):请注意,如果阵列阵列,上述内容将失败由
getBreadcrumb()返回,
非常大,超过了最大值计数,您可以将其传递到.push()
函数。您总是可以选择做自己当前正在做的事情,然后调用.flat(infinity)
在您的返回结果上。确实可以避免在您的阵列上添加额外的通行证。您可以通过返回一个新数组来克服这些问题,而返回的数组则会扩散到其中:
以您的
{id,slug,...}
对象为第一个,将创建一个新数组元素,然后是什么都没有的(如果parentpageId
是虚假的),或者呼叫返回的该数组中的数组元素,返回到getBreadcrumb(parentpageId)
)Rather than pushing the entire returned array from
getBreadcrumb
into your result, you can instead push the individual array elements from the returned array using the spread syntax (...
):Note that the above will fail if the array returned by
getBreadcrumb()
is very large an exceeds the max-argument count that you can pass to the.push()
function. You do always have the option of doing what you're currently doing, and then calling.flat(Infinity)
on your returned result. This does add an additional pass over your array though which can be avoided.You can overcome these issues by instead returning a new array, with your returned array spread into that:
The above will create a new array, with your
{id, slug, ...}
object as the first element, followed by either nothing (ifparentPageId
is falsy), or the array elements from that array returned by the call togetBreadcrumb(parentPageId)
)这是一种非回收方法,请使用a
循环,然后重新计算
getParentPage()
:Here's a non-recursive approach, use a
while
loop, and re-callgetParentPage()
: