संमिश्र घटकांबद्दल
मिश्रित घटक आहेत संयोजनएस च्या एकाधिक घटकपण r eआयडी किंवा एकल पालकांमध्ये प्रवेश करण्यायोग्य/ प्रतिबंधआहे लिहाENT, त्याचे मुख्य ध्येय विकसनशील घटक अशा प्रकारे बनवावे लागेल जीवन सोपे साठी लेखकांद्वारे सक्षम असणे फक्त ड्रॅग आणि ड्रॉप कराआहे लिहाENT एकाधिक ऐवजी. हे पुन्हा वापरता येण्याजोगे मॉड्यूलर घटक तयार करण्यात देखील मदत करते जे स्वतंत्रपणे किंवा इतर संमिश्र घटकांचा भाग म्हणून कार्य करू शकतात. काही प्रकरणांमध्ये, पालक/ प्रतिबंधआहे लिहाENT काहींचे स्वतःचे संवाद आहेत तर काहींना नाही. लेखक वैयक्तिकरित्या संपादित करा प्रत्येक घटक जोडा कारण ते स्वतंत्र म्हणून पृष्ठावर जोडले जातीलआहे लिहाENT,
एसपीए वि नॉन-एसपीए मधील मिश्रित घटक
SPA/HTL नसलेल्या जगात संमिश्र घटक विकसित करणे खूप सोपे आहे. आम्हाला फक्त मूल घटकाचा संसाधन मार्ग जोडण्याची आवश्यकता आहे डेटा-स्ली-संसाधने मूळ घटकाच्या HTL च्या आत. आम्ही खाली याबद्दल अधिक चर्चा करू.
AEM SPA आर्किटेक्चरमध्ये हे साध्य करण्यासाठी आणखी काही पायऱ्या आहेत. याचे कारण असे की केवळ लेखक घटकांचा JSON डेटा Sling Model Exporter द्वारे उघड केला जातो तर React घटक त्यांना मॅपिंग आणि डेटा वाचण्याचे भारी उचल करतो. JSON कडे नेस्टेड स्ट्रक्चर नसल्यास (पालकांच्या खाली सूचीबद्ध केलेले मूल घटक) प्रतिक्रिया घटकाला हे समजत नाही की आम्ही एक संमिश्र घटक तयार करण्याचा प्रयत्न करत आहोत. एकदा आमच्याकडे नेस्टेड स्ट्रक्चर उपलब्ध झाल्यावर, आम्ही स्टँडअलोन रिॲक्ट घटक म्हणून प्रत्येकाला पुनरावृत्ती आणि आरंभ करू शकतो.
खालील अंमलबजावणी विभागात अधिक तपशील दिले आहेत.
अंमलबजावणीमध्ये nऑन-एसपीए
हा घटक तयार करण्याचा एचटीएल/नॉन-एसपीए मार्ग पुढील चरणांद्वारे साध्य केला जाऊ शकतो.
पालक/कंटेनर घटकामध्ये संवाद किंवा डिझाइन संवाद नसल्यास, आम्हाला एक तयार करणे आवश्यक आहे CQ: टेम्पलेटनोडचा प्रकारNT: असंरचित आणि अंतर्गत CQ: टेम्पलेट नोड,, मिमीअधिक नोड प्रकारNT: असंरचित सह स्लिंग: संसाधन प्रकार घटकाचे पथ मूल्य समाविष्ट कराडी,
सर्व मुलांच्या घटकांसाठी याची पुनरावृत्ती करा. रेंडरच्या वेळी घटक सहजपणे समाविष्ट करण्यासाठी पालक/कंटेनर घटकाच्या HTL मध्ये खालील टॅग जोडा:
‘ @ संसाधन प्रकार =’,
खाली शीर्षक आणि प्रतिमा (संयुक्त) घटकाचे उदाहरण आहे जे कोर शीर्षक आणि प्रतिमा वापरून तयार केले गेले आहे. पालक/कंटेनर घटकामध्ये कोणताही संवाद नाही, म्हणून वर वर्णन केल्याप्रमाणे आम्हाला cq:template तयार करणे आवश्यक आहे. HTL ला data-sly-resource वापरून प्रतिमा आणि शीर्षक घटक समाविष्ट करणे आवश्यक आहे.
AEM SPA संपादक मध्ये अंमलबजावणी
एईएम एसपीए एडिटर (प्रतिक्रिया) मध्ये याची अंमलबजावणी करताना, प्रक्रिया खूप वेगळी असते कारण घटक पूर्णपणे एसपीए अनुप्रयोगाचा एक भाग म्हणून सादर केला जातो. वर नमूद केल्याप्रमाणे, AEM SPA मधील लेखक डेटा अजूनही JCR मध्ये संग्रहित केला जातो, परंतु JSON म्हणून प्रदर्शित केला जातो जो पारंपारिक HTL मध्ये वाचण्याऐवजी त्याच्या प्रतिक्रिया भागाशी मॅप केला जातो.
कोर आणि सानुकूल घटकांच्या मिश्रणाचा फायदा घेऊन आम्ही AEM SPA (React) मध्ये हेडर घटक कसे तयार करू शकतो ते आम्ही दाखवू. मूळ घटक जो या प्रकरणात शीर्षलेख आहे, तो नेस्टेड (JSON) संरचनेतील डेटा निर्यात करण्यासाठी त्याचे मूल म्हणून लिहिलेल्या सर्व घटकांना अद्यतनित केले जाईल. हे React घटकाला चाइल्ड नोड्ससह घटक म्हणून डेटा वाचण्यास आणि नंतर त्यावर पुनरावृत्ती करण्यास मदत करेल. पुढे, आपल्याला प्रत्येक नोडद्वारे परत केलेल्या वस्तूंचा समावेश करणे आवश्यक आहे जे नंतर मूल घटक सुरू करेल. बाल घटक आहेत:
- लोगो (मुख्य प्रतिमा)
- कोर नेव्हिगेशन
- दुय्यम नेव्हिगेशन
या अंमलबजावणीसाठी आम्हाला पुढील गोष्टींची आवश्यकता आहे:
- कोर इमेज आणि कोर नेव्हिगेशन प्रॉक्सी
- शोध आणि माझे खाते घटक
- ExportChildComponents स्लिंग मॉडेल
- पालक/कंटेनर हेडर घटक
1. कोर इमेज आणि कोर नेव्हिगेशनची प्रॉक्सी
- मूळ प्रतिमेची प्रॉक्सी तयार करा आणि लोगो म्हणून शीर्षक अद्यतनित करा.
- कोर नेव्हिगेशन घटकाची प्रॉक्सी तयार करा.
- या डेमोसाठी, प्रॉक्सीमध्ये कोणतेही कस्टमायझेशन नाहीत.
2. शोध आणि माझे खाते घटक
- एक स्वतंत्र शोध घटक तयार करा.
- हे हेडरमध्ये पुन्हा वापरले जाऊ शकते आणि कुठेही ड्रॅग आणि ड्रॉप केले जाऊ शकते.
- खाते व्यवस्थापन कॉन्फिगर करण्यासाठी फील्डसह माझे खाते घटक तयार करा.
3. ExportChildComponents मॉडेल स्लिंग
- निर्यात बाल घटक स्लिंग मॉडेल कोर कंटेनर स्लिंग मॉडेल लागू करते.
import com.adobe.cq.export.json.ComponentExporter; import com.drew.lang.annotations.NotNull; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.DefaultInjectionStrategy; import org.apache.sling.models.annotations.Exporter; import com.adobe.cq.export.json.ExporterConstants; import com.adobe.cq.wcm.core.components.models.Container; import java.util.Map; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.HashMap; import org.apache.commons.lang3.ArrayUtils; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.injectorspecific.*; import org.apache.sling.models.factory.ModelFactory; import com.adobe.cq.export.json.SlingModelFilter; //Sling Model annotation @Model(adaptables = SlingHttpServletRequest.class, adapters = { ExportChildComponents.class,ComponentExporter.class }, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) @Exporter( // Exporter annotation that serializes the model as JSON name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION, selector = ExporterConstants.SLING_MODEL_SELECTOR) public class ExportChildComponents implements Container{ private Map childrenModels; private String[] exportedItemsOrder; @ScriptVariable private Resource resource; @Self private SlingHttpServletRequest request; @OSGiService private SlingModelFilter slingModelFilter; @OSGiService private ModelFactory modelFactory; @NotNull @Override public Map getExportedItems() { if (childrenModels == null) { childrenModels = getChildrenModels(request, ComponentExporter.class); } Map exportChildrenModels = new HashMap(); exportChildrenModels.putAll(childrenModels); return exportChildrenModels; } @NotNull @Override public String[] getExportedItemsOrder() { if (exportedItemsOrder == null) { Map models = getExportedItems(); if (!models.isEmpty()) { exportedItemsOrder = models.keySet().toArray(ArrayUtils.EMPTY_STRING_ARRAY); } else { exportedItemsOrder = ArrayUtils.EMPTY_STRING_ARRAY; } } return Arrays.copyOf(exportedItemsOrder,exportedItemsOrder.length); } private Map getChildrenModels(@NotNull SlingHttpServletRequest request, @NotNull Class modelClass) { Map models = new LinkedHashMap<>(); for (Resource child : slingModelFilter.filterChildResources(resource.getChildren())) { T model = modelFactory.getModelFromWrappedRequest(request, child, modelClass); if (model != null) { models.put(child.getName(), model); } } return models; } } ...
- हे पालक नोड अंतर्गत जतन केलेल्या बाल घटकांवर पुनरावृत्ती करण्यास मदत करते.
- नंतर ते सर्व त्यांच्या स्लिंग मॉडेल एक्सपोर्टरद्वारे सिंगल JSON आउटपुट म्हणून निर्यात करा.
import com.adobe.cq.export.json.ComponentExporter; { ":items": { "root": { "columnClassNames": { "header": "aem-GridColumn aem-GridColumn--default--12" }, "gridClassNames": "aem-Grid aem-Grid--12 aem-Grid--default--12", "columnCount": 12, ":items": { "header": { "id": "header-346949959", ":itemsOrder": [ "logo", "navigation", "search", "account" ], ":type": "perficient/components/header", ":items": { "logo": { "id": "image-ee58d4cd48", "linkType": "", "tagLinkType": "", "displayPopupTitle": true, "decorative": false, "srcUriTemplate": "/content/experience-fragments/perficient/us/en/site/header/master/_jcr_content/root/header/logo.coreimg{.width}.png/1705295980301/perficient-logo-horizontal.png", "lazyEnabled": true, "title": "Logo", "uuid": "799c7831-264c-42c0-be02-1d0cbb747bd2", "areas": [], "alt": "NA", "src": "/content/experience-fragments/perficient/us/en/site/header/master/_jcr_content/root/header/logo.coreimg.png/1705295980301/perficient-logo-horizontal.png", "widths": [], ":type": "perficient/components/logo" }, "navigation": { "id": "navigation-1727181688", "items": [ { "id": "navigation-cd54619f8f-item-12976048d7", "path": "/content/react-spa/us/en/cases", "level": 0, "active": false, "current": false, "title": "Link 1", "url": "/content/react-spa/us/en/cases.html", "lastModified": 1705203487624, ":type": "perficient/components/structure/page" }, { "id": "navigation-cd54619f8f-item-438eb66728", "path": "/content/react-spa/us/en/my-onboarding-cases", "level": 0, "active": false, "current": false, "title": "Link 2", "url": "/content/react-spa/us/en/my-onboarding-cases.html", "lastModified": 1705203496764, ":type": "perficient/components/structure/page" }, { "id": "navigation-cd54619f8f-item-e8d85a3188", "path": "/content/react-spa/us/en/learning-resources", "level": 0, "active": false, "current": false, "title": "Link 3", "url": "/content/react-spa/us/en/learning-resources.html", "lastModified": 1705203510651, ":type": "perficient/components/structure/page" }, { "id": "navigation-cd54619f8f-item-d1553683aa", "path": "/content/react-spa/us/en/Reports", "children": [], "level": 0, "active": false, "current": false, "title": "Link 5", "url": "/content/react-spa/us/en/Reports.html", "lastModified": 1705203601382, ":type": "perficient/components/structure/page" } ], ":type": "perficient/components/navigation" }, "search": { "id": "search-1116154524", "searchFieldType": "navbar", ":type": "perficient/components/search" }, "account": { "id": "account-1390371799", "accountConfigurationFields": [], "logoutLinkType": "", "helpText": "Account", "logoutText": "Sign Out", ":type": "perficient/components/account" } } } }, ":itemsOrder": [ "header" ], ":type": "perficient/components/core/container" } } } ...
4. पालक/कंटेनर हेडर घटक
- एक शीर्षलेख घटक तयार करा जो कोर कंटेनर घटकाचा विस्तार आहे.
- हेडर घटक संवादामध्ये अतिरिक्त टॅब म्हणून शोध घटक संवाद समाविष्ट करा.
- खाते टॅब समाविष्ट करा जो वापरकर्ता खाते व्यवस्थापनासाठी फील्डसह सानुकूल टॅब आहे.
- एक cq:टेम्प्लेट तयार करा ज्यामध्ये चाइल्ड नोड्स त्यांच्या संबंधित संसाधन मार्गांकडे निर्देश करतात.
- हे स्लिंग मॉडेल एक्सपोर्टर वापरून लिखित डेटा निर्यात करण्यात मदत करेल.
- तयार करा हेडर मॉडेल इम्प्ल ते पसरते निर्यात बाल घटक (चरण 3 मध्ये बनविलेले). हे केवळ पालकच नव्हे तर त्यांच्या मुलांचा (लोगो, नेव्हिगेशन आणि शोध) JSON डेटा निर्यात करते.
import com.adobe.cq.export.json.ComponentExporter; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.models.annotations.DefaultInjectionStrategy; import org.apache.sling.models.annotations.Exporter; import org.apache.sling.models.annotations.Model; import com.adobe.cq.export.json.ComponentExporter; import com.adobe.cq.export.json.ExporterConstants; import com.chc.ecchub.core.models.ExportChildComponents; import com.chc.ecchub.core.models.nextgen.header.HeaderModel; @Model(adaptables = SlingHttpServletRequest.class, adapters = { HeaderModel.class, ComponentExporter.class}, resourceType = HeaderModelImpl.RESOURCE_TYPE, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) @Exporter( // Exporter annotation that serializes the model as JSON name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION) public class HeaderModelImpl extends ExportChildComponents implements HeaderModel{ static final String RESOURCE_TYPE = "perficient/components/header"; @Override public String getExportedType() { return RESOURCE_TYPE; } } ...
- हेडरसाठी प्रतिक्रिया समतुल्य तयार करा जे कोर कंटेनर विस्तारित करते आणि वर तयार केलेल्या हेडर घटकाचे नकाशे करते.
import { Container, MapTo, withComponentMappingContext } from '@adobe/aem-react-editable-components'; import { useState } from "react"; import { NavigationComp, NavigationConfig } from "./Navigation"; import { LogoComp, LogoConfig } from "../../components/Logo"; import { SearchComp } from "../../components/Search"; import { SecondaryNavigation } from "./SecondaryNavigation"; export const HeaderEditConfig = { emptyLabel: 'Header' }; export default class Header extends Container { render() { return ( <> > ) } } const selectedComponent = (props, selectedCqType) => { let selectedComponentProps; props?.headerData?.forEach((data) => { if (data.props?.cqType === selectedCqType) { selectedComponentProps = data; } }); return selectedComponentProps; } const HeaderComp = (props) => { const [searchModalOverlay, setSearchModalOverlay] = useState(false); const searchProps = selectedComponent(props, 'perficient/components/search'); const logoProps = selectedComponent(props, 'perficient/components/logo'); const navProps = selectedComponent(props, 'perficient/components/navigation'); return ( <>
> ) } MapTo('ECCHub/components/nextgen/header/navigation')(NavigationComp, NavigationConfig); MapTo('ECCHub/components/nextgen/header/logo')(LogoComp, LogoConfig); MapTo('ECCHub/components/nextgen/header/header')(withComponentMappingContext(Header), HeaderEditConfig);
- याव्यतिरिक्त, लोगो आणि नेव्हिगेशनसाठी नकाशा जोडा कारण ते मूल घटक म्हणून निर्यात केले जातात. हेडर कोर कंटेनरचा विस्तार करत असल्याने, चाइल्ड घटक गुणधर्म super.childcomponents द्वारे उपलब्ध आहेत
import { useEffect } from 'react'; import { MapTo } from '@adobe/aem-react-editable-components'; import * as constants from '../../../../utils/constants'; import { toggleHeaderForUsers } from '../../../../utils/genericUtil'; import { useDispatch } from "react-redux"; import { BreadcrumbActions } from '../../../../store/Breadcrumb/BreadcrumbSlice'; export const NavigationConfig = { emptyLabel: 'Navigation', isEmpty: function() { return true; } }; export const NavigationComp = (navProps) => { return (
{/* लेखक लिंकद्वारे नेव्हिगेशन मॅप करतात आणि लिंक शीर्षक आणि URL प्रस्तुत करतात. */} {navProps?.items.map((आयटम, अनुक्रमणिका) =>
,
} MapTo(“perficient/components/navigation”)(navigationComp, navigationConfiguration);
गुंतवणुकीचे मूल्य
एकत्रित घटक हे एक उपयुक्त वैशिष्ट्य आहे ज्याचा फायदा घेतला जाऊ शकतो कारण ते वैयक्तिक घटकांची मॉड्यूलरिटी आणि पुन: उपयोगिता राखून लेखकांना खूप मदत करतात. जरी HTL दृष्टिकोनाच्या तुलनेत SPA फ्रेमवर्कवर अनुभव निर्माण करण्यासाठी अतिरिक्त प्रयत्न करणे आवश्यक आहे, तरीही ते गुंतवणुकीचे योग्य आहे कारण ते एक-वेळचे सेटअप आहे आणि कोणत्याही घटकासाठी कितीही वेळा वापरले जाऊ शकते कारण हे अगदी सामान्य आहे.