Web组件
[AEM Headlessas a Cloud Service]{class="badge informative"}
示例应用程序是探索Adobe Experience Manager (AEM)的Headless功能的绝佳方法。 此Web组件应用程序演示了如何使用AEM的GraphQL API通过持久查询来查询内容,以及如何呈现部分UI(使用纯JavaScript代码完成)。
具有AEM Headless的
在GitHub🔗上查看源代码
先决条件 prerequisites
应在本地安装以下工具:
AEM要求
Web组件可与以下AEM部署选项配合使用。
- AEM as a Cloud Service
- 使用AEM Cloud Service SDK进行本地设置
- 需要JDK 11(如果连接到本地AEM 6.5或AEM SDK)
此示例应用依赖于要安装basic-tutorial-solution.content.zip,并且所需的部署配置已准备就绪。
person.js
文件中提供了身份验证,则它可以从AEM Author获取内容。使用方法
-
克隆
adobe/aem-guides-wknd-graphql
存储库:code language-shell $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
-
导航到
web-component
子目录。code language-shell $ cd aem-guides-wknd-graphql/web-component
-
编辑
.../src/person.js
文件以包含AEM连接详细信息:在
aemHeadlessService
对象中,更新aemHost
以指向您的AEM Publish服务。code language-plain # AEM Server namespace aemHost=https://publish-p123-e456.adobeaemcloud.com # AEM GraphQL API and Persisted Query Details graphqlAPIEndpoint=graphql/execute.json projectName=my-project persistedQueryName=person-by-name queryParamName=name
如果连接到AEM Author服务,请在
aemCredentials
对象中提供本地AEM用户凭据。code language-plain # For Basic auth, use AEM ['user','pass'] pair (for example, when connecting to local AEM Author instance) username=admin password=admin
-
打开终端并运行来自
aem-guides-wknd-graphql/web-component
的命令:code language-shell $ npm install $ npm start
-
新的浏览器窗口将打开一个静态HTML页,该页包含位于http://localhost:8080的Web组件。
-
人员信息 Web组件显示在网页上。
代码
以下摘要介绍了Web组件的构建方式、它如何连接到AEM Headless以使用GraphQL持久查询检索内容,以及数据如何呈现。 完整的代码可在GitHub上找到。
Web组件HTML标记
可重复使用的Web组件(又称自定义元素)<person-info>
已添加到../src/assets/aem-headless.html
HTML页。 它支持host
和query-param-value
属性来驱动组件的行为。 host
属性的值覆盖person.js
中aemHeadlessService
对象的aemHost
值,并且query-param-value
用于选择要呈现的人员。
<person-info
host="https://publish-p123-e456.adobeaemcloud.com"
query-param-value="John Doe">
</person-info>
Web组件实施
person.js
定义了Web组件功能,下面是其中的关键亮点。
PersonInfo元素实施
<person-info>
自定义元素的类对象通过使用connectedCallback()
生命周期方法、附加影子根、获取GraphQL持久查询和DOM操作来创建自定义元素的内部影子DOM结构来定义功能。
// Create a Class for our Custom Element (person-info)
class PersonInfo extends HTMLElement {
constructor() {
...
// Create a shadow root
const shadowRoot = this.attachShadow({ mode: "open" });
...
}
...
// lifecycle callback :: When custom element is appended to document
connectedCallback() {
...
// Fetch GraphQL persisted query
this.fetchPersonByNamePersistedQuery(headlessAPIURL, queryParamValue).then(
({ data, err }) => {
if (err) {
console.log("Error while fetching data");
} else if (data?.personList?.items.length === 1) {
// DOM manipulation
this.renderPersonInfoViaTemplate(data.personList.items[0], host);
} else {
console.log(`Cannot find person with name: ${queryParamValue}`);
}
}
);
}
...
//Fetch API makes HTTP GET to AEM GraphQL persisted query
async fetchPersonByNamePersistedQuery(headlessAPIURL, queryParamValue) {
...
const response = await fetch(
`${headlessAPIURL}/${aemHeadlessService.persistedQueryName}${encodedParam}`,
fetchOptions
);
...
}
// DOM manipulation to create the custom element's internal shadow DOM structure
renderPersonInfoViaTemplate(person, host){
...
const personTemplateElement = document.getElementById('person-template');
const templateContent = personTemplateElement.content;
const personImgElement = templateContent.querySelector('.person_image');
personImgElement.setAttribute('src',
host + (person.profilePicture._dynamicUrl || person.profilePicture._path));
personImgElement.setAttribute('alt', person.fullName);
...
this.shadowRoot.appendChild(templateContent.cloneNode(true));
}
}
注册<person-info>
元素
// Define the person-info element
customElements.define("person-info", PersonInfo);
跨源资源共享(CORS)
此Web组件依赖于在目标AEM环境中运行的基于AEM的CORS配置,并假定主机页面在开发模式下运行于http://localhost:8080
,以下是本地AEM Author服务的CORS OSGi配置示例。
请检查各个AEM服务的部署配置。