Artem Zur
Artem Zur

Reputation: 368

How to share CMSComponentData between independent components in Spartacus

Let's imagine that we have CMS Component:

ConfigModule.withConfig(<CmsConfig>{
  cmsComponents: {
    CmsSupportComponent: {
      component: SupportComponent,
    },
  },
}),

But from inside we have to open another Angular component which also needs the same CMSComponentData. Simple Angular component relates to the same Angular module.

I know that we can do it via Angular Service, common for Angular manner (this requires some handy work). But maybe Spartacus has some approaches similar to:

ConfigModule.withConfig({
  cmsComponents: {
    CmsSupportComponent: {
        component: SupportComponent,
        providers: [
        {
          provide: SupportComponentService,
          useClass: SupportComponentService,
          deps: [CmsComponentData]
        }
      ];
    }
  }
});

and we can share injected CmsComponentData via common Service for independent components.

Update 21.01.2021:

When we say - 'open' Angular component from inside CMS Component, it's meaning something like that:

this.modalService.open(SupportFormComponent);

As you can see SupportFormComponent is not child component and don't have any relationships with CmsSupportComponent.

Upvotes: 0

Views: 815

Answers (4)

Aleksandr Terentev
Aleksandr Terentev

Reputation: 1

Second way.

You can get data about cms-component by uid with help CmsService getComponentData

https://github.com/SAP/spartacus/blob/develop/projects/core/src/cms/facade/cms.service.ts#L67

Upvotes: 0

Aleksandr Terentev
Aleksandr Terentev

Reputation: 1

One way:

this.modalService.open returns ModalRef. It is the instance creating component.

const  modal = this.modalService.open(SupportFormComponent);
modal.someProp = someData;

and in SupportFormComponent you should have public class property or @Input someProp

You can see example here https://github.com/SAP/spartacus/blob/develop/projects/storefrontlib/src/cms-components/cart/add-to-cart/add-to-cart.component.ts#L103

Upvotes: 0

dunqan
dunqan

Reputation: 974

Angular uses hierarchical dependency tree, so any instance that you can inject in a parent component, you can also inject inside child component, unless it's shadowed be new provider (but even then @SkipSelf may help).

So, as CmsComponentData is provided automatically by Spartacus, when instantiating specific cms component, it should be possible to inject it to any child component (inside this component) by just injecting CmsComponentData (you'll get the same instance).

In case of some complex configuration, when you are providing different CmsComponentData in child components, you can always wrap it into service (or provide as different token) in the first (top) component that gets it, but I think in your case it should not be needed.

Upvotes: 3

i042416
i042416

Reputation: 366

as defined in Spartacus documentation:

The CMS data that is related to a component is provided to the component by the CmsComponentData service during instantiation. The CmsComponentData service contains the component uid, and also data$, which is an observable to the component payload. By making use of the Angular dependency injection (DI) system, components and component-specific services can use the CmsComponentData.

it's recommended way to use Angular DI to inject CmsComponentData service and used in your components.

Best Regards, Jerry

Upvotes: 0

Related Questions