Есть ли поддержка настраиваемого AbstractCMSComponentContainer в Spartacus (SmartEdit)?

В бэкэнде у меня была следующая модель данных:

AccordionComponentContainer extends CMSTabParagraphContainer
AccordionItemComponent extends SimpleCMSComponent

Контейнер, расширяющий CMSTabParagraphContainer, потому что расширение AbstractCMSComponentContainer - это головная боль (сгенерированные классы jalo должны быть адаптированы, но в данном случае это не важно, только для понимания.

Теперь у меня есть компонент в Спартаке CmsAccordionComponent. Я представил отображение компонентов:

AccordionComponentContainer: { 
  component: CmsAccordionComponent, 
},

В моем компонентном html файле у меня есть что-то вроде этого:

<h2>{{headline$ | async}}</h2> 
<ul> 
  <ng-container *ngFor="let component of components$ | async; let i = index"> 
    <li>{{component.content}}</li>
  </ng-container> 
</ul>

Я использовал файлы вprojects/storefrontlib/src/cms-components/content/tab-paragraph-containerв качестве ссылки для моей реализации (например, реализация компонента). Ожидание ng-шаблона (cxOutlet):

<ng-template [cxOutlet]="component.flexType" [cxOutletContext]="{}">
  <ng-container [cxComponentWrapper]="component"></ng-container> 
</ng-template>

Раньше я пробовал то же решение, что и CMSTabParagraphContainer. По какой-то причине это не сработает в моем проекте. Я представил собственный компонент и сопоставление для детей (AccordionItemComponent), но это не сработало. Дочерние компоненты не показаны.

Поэтому я использовал свое решение, описанное выше. В моем решении компоненты отображаются (также дочерние компоненты), но я не могу редактировать их в SmartEdit. Возможно, это связано с этой проблемой: https://github.com/SAP/spartacus/issues/1484.

В целях тестирования я добавил "нормальный" CMSTabParagraphContainer с CMSParagraphComponent в свой слот контента в бэк-офисе. И я могу редактировать первый компонент CMSParagraphComponent, который отображается в SmartEdit. К сожалению, я не могу добавлять новые абзацы в CMSTabParagraphContainer. Поэтому я считаю, что решение ng-template (cxOutlet) лучше моего.

Не могли бы вы объяснить, как работают TabParagraphContainerComponent и фрагмент ng-template (cxOutlet)? Также я думаю, что это следует учитывать в билете о выпуске github (https://github.com/SAP/spartacus/issues/1484), чтобы CMSTabParagraphContainer (AbstractCMSComponentContainer) лучше поддерживался в Spartacus (SmartEdit).

Спасибо за вашу помощь!

1 ответ

Решение

Самая важная часть - это cxComponentWrapper. Эта директива принимает данные слота компонента и отображает компонент внутри.

В cxComponentWrapper требуется следующий набор данных для каждого компонента:

{
  flexType: item.typeCode,
  typeCode: item.typeCode,
  uid: item?.uid
}

Типичная реализация шаблона компонента контейнера будет перебирать различные компоненты и применять директиву:

<ng-container *ngFor="let item of items$ | async">
  <ng-container
    [cxComponentWrapper]="{
      flexType: item.typeCode,
      typeCode: item.typeCode,
      uid: item?.uid
    }"
  >
  </ng-container>
</ng-container>

Проблема, с которой вы, вероятно, столкнетесь, - это отсутствие компонента typeв контейнере компонент cms data. API cms будет отображать только UID компонентов для различных вложенных компонентов. Вам нужно получить тип компонента из серверной части, используяCmsService.getComponentData. Это нужно сделать для каждого uid компонента. Если вы сделаете это в цикле, Spartacus фактически объединит различные вызовы CmsService.getComponentData и выполнит один вызов серверной части.

Пример такой реализации можно найти по адресу https://github.com/SAP/spartacus/blob/746a15c1b63998065b0ceea96f4da052829533fb/projects/storefrontlib/src/cms-components/content/banner-carousel/banner-carousel.component.ts.

Другие вопросы по тегам