next.js Strapi控制器未填充嵌套的可重复组件

gcmastyq  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(83)

我正在使用Strapi v4,在API响应中填充嵌套的可重复组件时遇到了问题。我在另一个组件faqs中有一个可重复组件faq_item。但是,当我尝试在自定义控制器中使用populate选项填充faq_item时,它不会返回嵌套数据。
下面是我的组件的结构:

  • klubr_house(集合类型)
  • club_presentation(动态区域)
  • faqs(组件)
  • faq_item(可重复组件)

下面是我的控制器的findOne方法:

"use strict";

const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController("api::klubr.klubr", ({ strapi }) => ({
  async findOne(ctx) {
    const { id } = ctx.params;
    const entity = await strapi.db.query("api::klubr.klubr").findOne({
      where: { slug: id },
      populate: {
        klubr_house: {
          populate: {
            club_presentation: {
              populate: {
                faqs: {
                  populate: {
                    faq_item: true, // This should populate all fields within each faq_item
                  },
                },
                // ... other fields
              },
            },
            // ... other relations
          },
        },
        // ... other fields
      },
    });
    const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
    return this.transformResponse(sanitizedEntity);
  },
}));

字符串

bybem2ql

bybem2ql1#

我想出了解决办法
解决方法:
我修改了自定义控制器中klubr内容类型的findOne方法。关键是创建一个递归函数getFullPopulateObject,该函数为Strapi的查询系统构造一个完整的填充对象。该函数考虑不同的字段类型,如组件,动态区域,关系和媒体。

"use strict";

     const { createCoreController } = require("@strapi/strapi").factories;

module.exports = createCoreController("api::klubr.klubr", ({ strapi }) => ({
  async findOne(ctx) {
    const { id } = ctx.params;
    const entity = await strapi.db.query("api::klubr.klubr").findOne({
      where: { slug: id },
      ...getFullPopulateObject("api::klubr.klubr"),
    });
    const sanitizedEntity = await this.sanitizeOutput(entity, ctx);
    return this.transformResponse(sanitizedEntity);
  },
}));

const { isEmpty, merge } = require("lodash/fp");

const getModelPopulationAttributes = (model) => {
  if (model.uid === "plugin::upload.file") {
    const { related, ...attributes } = model.attributes;
    return attributes;
  }

  return model.attributes;
};

const getFullPopulateObject = (modelUid, maxDepth = 20, parentModelUid = null) => {
  if (maxDepth <= 1) {
    return true;
  }
  if (modelUid === "admin::user") {
    return undefined;
  }

  const populate = {};
  const model = strapi.getModel(modelUid);
  for (const [key, value] of Object.entries(
    getModelPopulationAttributes(model)
  )) {
    if (value) {
      if (value.type === "relation" && value.target === parentModelUid) {
        continue; 
      }
      if (value.type === "component") {
        populate[key] = getFullPopulateObject(value.component, maxDepth - 1);
      } else if (value.type === "dynamiczone") {
        const dynamicPopulate = value.components.reduce((prev, cur) => {
          const curPopulate = getFullPopulateObject(cur, maxDepth - 1);
          return curPopulate === true ? prev : merge(prev, curPopulate);
        }, {});
        populate[key] = isEmpty(dynamicPopulate) ? true : dynamicPopulate;
      } else if (value.type === "relation") {
        const relationPopulate = getFullPopulateObject(
          value.target,
          maxDepth - 1,
          modelUid // Pass the current model as parent
        );
        if (relationPopulate) {
          populate[key] = relationPopulate;
        }
      
        
      } else if (value.type === "media") {
        populate[key] = true;
      }
    }
  }
  return isEmpty(populate) ? true : { populate };
};

字符串
这种方法成功地填充了findOne查询中的所有相关字段。我希望这个解决方案可以帮助其他使用Strapi中自定义控制器的人。

相关问题