我正在通過 Contentful API 處理資料,并且正在嘗試構建我正在構建的網站的結構。我正在使用 GraphQL API 并獲取 Contentful 頁面,但是,由于速率限制,在獲取參考和層次結構時,我無法深入查詢。
這讓我查詢了我的“頁面”內容型別并獲取每個頁面并獲取其父頁面 ID,僅向上一級。理論上,如果我對每個頁面都這樣做,我可以通過在構建期間運行一些 JS 來遞回地構建頁面結構(我正在使用 Eleventy 來構建站點)。
我需要一個函式來為我生成一個面包屑陣列,理想情況下,我會為該函式提供一個頁面的 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
},
]
]
]
援助將不勝感激!
uj5u.com熱心網友回復:
getBreadcrumb您可以使用擴展語法 ( ...)從回傳的陣列中推送單個陣列元素,而不是將整個回傳的陣列推送到結果中:
breadcrumbArray.push(...getBreadcrumb(parentPageId))
請注意,如果回傳的陣列getBreadcrumb()非常大并且超過您可以傳遞給.push()函式的最大引數計數,則上述操作將失敗。您始終可以選擇執行當前正在執行的操作,然后呼叫.flat(Infinity)回傳的結果。這確實會在您的陣列上增加一個額外的傳遞,盡管這是可以避免的。您可以通過回傳一個新陣列來克服這些問題,并將回傳的陣列傳播到:
function getBreadcrumb(pageId) {
const { id, slug, title, parentPageId } = getParentPage(pageId);
return [{ id, slug, title, parentPageId }, ...(parentPageId ? getBreadcrumb(parentPageId) : [])];
}
上面將創建一個新陣列,將您的{id, slug, ...}物件作為第一個元素,然后是任何內容(如果parentPageId是假的),或者呼叫回傳的該陣列中的陣列元素getBreadcrumb(parentPageId))
uj5u.com熱心網友回復:
這是一種非遞回方法,使用while回圈并重新呼叫getParentPage():
function getBreadcrumb(pageId) {
let breadcrumbArray = [];
let { id, slug, title, parentPageId } = getParentPage(pageId);
breadcrumbArray.push({ id, slug, title, parentPageId });
// while parentPageId === false, execute getParentPage with found id
while ( parentPageId ) {
pageObj = getParentPage(id);
breadcrumbArray.push(pageObj);
// update found id and parentPageId for while loop
id = pageObj.parentPageId;
parentPageId = pageObj.parentPageId;
}
return breadcrumbArray;
}
// okay to ignore the rest...
// parent page mock up, randomly return a parentPageId that equates to false
function getParentPage(pageId) {
return { id: 1, slug: "slug", title: "title", parentPageId: Math.floor(Math.random() * 2) };
}
console.log(getBreadcrumb(3));
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/487719.html
標籤:javascript 数组 递归 满足的 十一
下一篇:在遞回地反轉鏈表時,哪個先出現?
