0

In the following childComponent, data is prepared by processing the params public property.

childComponent.html

<template>     
    <lightning-accordion active-section-name="" allow-multiple-sections-open class="">
        <template for:each={data} for:item="dataItem">
            <div key={dataItem.key}>
                <lightning-accordion-section name={dataItem.name} label={dataItem.label}>
                    <div>
                        <slot name="bodyContent"></slot>
                    </div>
                </lightning-accordion-section>
            </div>
    </lightning-accordion>
</template>

I want to insert markup in the slot of the above component from parentComponent such that the markup (detailsComponent) will render according to the iterator variable dataItem of childComponent that will be set to its detailsParam public property, something like below:

parentComponent.html

<template>
    <c-child-component params={parameters} >
        <div slot="bodyContent">
            <c-details-component details-param={xxx}></c-details-component>
        </div>
    </c-child-component>
</template>

Is it possible to achieve this?

I'm aware that I can have for:each iterator in parentComponent instead and then set it to detailsParam (similar to what is mentioned here). However, I want to avoid this since I want all the processing to be handled by childComponent and detailsComponent only.

Currently, what I have achieved: childComponent.html

<template>     
    <lightning-accordion active-section-name="" allow-multiple-sections-open class="">
        <template for:each={data} for:item="dataItem">
            <div key={dataItem.key}>
                <lightning-accordion-section name={dataItem.name} label={dataItem.label}>
                    <c-details-component details-param={dataItem}></c-details-component>
                </lightning-accordion-section>
            </div>
    </lightning-accordion>
</template>

This makes my childComponent tightly bound to detailsComponent and I can't really reuse the accordion a lot.

1 Answer 1

1

You can't do it directly the way you envision, because the slotted component wouldn't get the right data. Either the iteration needs to happen in the parent, or the child has to patch in the information after rendering. For example, in the child, this would probably work:

renderedCallback() {
  const slottedElements = [...(this.querySelectorAll('c-details-component')||[])];
  if(!slottedElements.length) {
    return;
  }
  this.params.data.forEach(
    (datum, index) => { slottedElements[index].someAttribute = datum.value }
  );
}

I'm taking some liberties here, but this should be approximately correct. Note that we still have a dependency on the component name, but we can fix that with a public property:

@api queryComponentName;
  const slottedElements = [...(this.querySelectorAll(this.queryComponentName)||[])];
<c-child-component params={parameters} query-component-name="c-details-component">

It's generally a bad idea to try and do this, however. It'd be far easier to iterate from the parent any components that need to be rendered that way.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .