了解如何扩展要与AEM SPA编辑器一起使用的现有核心组件。 了解如何扩展现有组件是一种强大的技术,可用于自定义和扩展AEM SPA Editor实施的功能。
sling:resourceSuperType
.在本章中,新增了 Card
组件已创建。 此 Card
组件扩展 图像核心组件 添加其他内容字段,如“标题”和“行动号召”按钮,为SPA中的其他内容执行Teaser角色。
查看所需的工具和设置说明 本地开发环境.
通过Git下载本教程的起点:
$ git clone git@github.com:adobe/aem-guides-wknd-spa.git
$ cd aem-guides-wknd-spa
$ git checkout Angular/extend-component-start
使用Maven将代码库部署到本地AEM实例:
$ mvn clean install -PautoInstallSinglePackage
如果使用 AEM 6.x 添加 classic
个人资料:
$ mvn clean install -PautoInstallSinglePackage -Pclassic
为传统安装完成的包 WKND引用站点. 图片提供者: WKND引用站点 在WKND SPA上重用。 可使用以下方式安装软件包 AEM包管理器.
您始终可以在以下位置查看完成的代码 GitHub 或通过切换到分行在本地签出代码 Angular/extend-component-solution
.
章节启动程序代码提供了初始卡组件。 Inspect是信息卡实施的起点。
在您选择的IDE中,打开 ui.apps
模块。
导航到 ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/card
并查看 .content.xml
文件。
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Component"
jcr:title="Card"
sling:resourceSuperType="wknd-spa-angular/components/image"
componentGroup="WKND SPA Angular - Content"/>
属性 sling:resourceSuperType
指向 wknd-spa-angular/components/image
指示 Card
组件继承了WKND SPA图像组件的功能。
Inspect文件 ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image/.content.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:Component"
jcr:title="Image"
sling:resourceSuperType="core/wcm/components/image/v2/image"
componentGroup="WKND SPA Angular - Content"/>
请注意 sling:resourceSuperType
指向 core/wcm/components/image/v2/image
. 这表示WKND SPA图像组件继承了核心组件图像的功能。
也称为 代理模式 Sling资源继承是一种强大的设计模式,它允许子组件继承功能并在需要时扩展/覆盖行为。 Sling继承支持多级继承,因此最终将支持新的 Card
组件继承核心组件图像的功能。
许多开发团队都努力做到自我(不要重复自己)。 通过Sling继承,可以对AEM执行此操作。
在 card
文件夹,打开文件 _cq_dialog/.content.xml
.
此文件是 Card
组件。 如果使用Sling继承,则可以使用 Sling资源合并器 覆盖或延伸对话框的各个部分。 在此示例中,向对话框中添加了一个新选项卡,用于从作者捕获其他数据以填充卡片组件。
类似属性 sling:orderBefore
允许开发人员选择插入新选项卡或表单字段的位置。 在本例中, Text
标签插入到 asset
选项卡。 为了充分利用Sling资源合并器,重要的是要知道原始的对话框节点结构 图像组件对话框.
在 card
文件夹,打开文件 _cq_editConfig.xml
. 此文件指示AEM创作UI中的拖放行为。 扩展图像组件时,资源类型必须与组件本身匹配,这一点很重要。 查看 <parameters>
节点:
<parameters
jcr:primaryType="nt:unstructured"
sling:resourceType="wknd-spa-angular/components/card"
imageCrop=""
imageMap=""
imageRotate=""/>
大多数组件不需要 cq:editConfig
、图像和图像组件的子后代是例外。
在IDE中,切换到 ui.frontend
模块,导航到 ui.frontend/src/app/components/card
:
Inspect文件 card.component.ts
.
该组件已被清除以映射到AEM Card
使用标准的组件 MapTo
函数。
MapTo('wknd-spa-angular/components/card')(CardComponent, CardEditConfig);
查看三个 @Input
的类中的参数 src
, alt
、和 title
. 这些是映射到Angular组件的AEM组件中的JSON值。
打开文件 card.component.html
:
<div class="card" *ngIf="hasContent">
<app-image class="card__image" [src]="src" [alt]="alt" [title]="title"></app-image>
</div>
在此示例中,我们选择重用现有的Angular图像组件 app-image
只需传递 @Input
参数来源 card.component.ts
. 在稍后的教程中,添加并显示其他属性。
使用这个初始 Card
实施回顾AEM SPA编辑器中的功能。 要查看初始 Card
组件需要更新模板策略。
将入门级代码部署到AEM的本地实例(如果尚未部署):
$ cd aem-guides-wknd-spa
$ mvn clean install -PautoInstallSinglePackage
导航到SPA页面模板,网址为 http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.
更新布局容器的策略以添加新的 Card
组件作为允许的组件:
保存对策略所做的更改,并遵守 Card
组件作为允许的组件:
接下来,创作 Card
组件使用AEM SPA编辑器。
导航到 http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.
In Edit
模式,添加 Card
组件到 Layout Container
:
将图像从资产查找器拖放到 Card
组件:
打开 Card
“组件”对话框,并注意添加了 文本 选项卡。
在 文本 选项卡:
信息卡路径 — 在SPA主页下方选择一页。
CTA文本 — “了解更多”
卡片标题 — 留空
从链接的页面获取标题 — 选中复选框以指示true。
更新 资源元数据 选项卡以添加值 替换文本 和 题注.
更新对话框后,当前未显示其他更改。 要向Angular组件公开新字段,我们需要更新的Sling模型 Card
组件。
打开新选项卡并导航到 CRXDE-Lite. Inspect下的内容节点 /content/wknd-spa-angular/us/en/home/jcr:content/root/responsivegrid
以查找 Card
组件内容。
观察该属性 cardPath
, ctaText
, titleFromPage
对话框持久保留。
要最终将组件对话框中的值显示给Angular组件,我们需要更新填充的JSON的Sling模型 Card
组件。 我们还有机会实施两种业务逻辑:
titleFromPage
到 true,返回由指定的页面的标题 cardPath
否则,返回值 cardTitle
文本字段。cardPath
.返回您选择的IDE并打开 core
模块。
打开文件 Card.java
在 core/src/main/java/com/adobe/aem/guides/wknd/spa/angular/core/models/Card.java
.
请注意 Card
接口当前扩展 com.adobe.cq.wcm.core.components.models.Image
因此继承了 Image
界面。 此 Image
界面已扩展 ComponentExporter
接口,该接口允许将Sling模型导出为JSON并由SPA编辑器进行映射。 因此,我们不需要显式扩展 ComponentExporter
界面,就像我们在 自定义组件章节.
将以下方法添加到接口:
@ProviderType
public interface Card extends Image {
/***
* The URL to populate the CTA button as part of the card.
* The link should be based on the cardPath property that points to a page.
* @return String URL
*/
public String getCtaLinkURL();
/***
* The text to display on the CTA button of the card.
* @return String CTA text
*/
public String getCtaText();
/***
* The date to be displayed as part of the card.
* This is based on the last modified date of the page specified by the cardPath
* @return
*/
public Calendar getCardLastModified();
/**
* Return the title of the page specified by cardPath if `titleFromPage` is set to true.
* Otherwise return the value of `cardTitle`
* @return
*/
public String getCardTitle();
}
这些方法通过JSON模型API公开,并传递到Angular组件。
打开 CardImpl.java
. 这是的实施 Card.java
界面。 为加速教程,已部分修剪此实施。 请注意使用 @Model
和 @Exporter
注释,以确保能够通过Sling模型导出器将Sling模型序列化为JSON。
CardImpl.java
也会使用 Sling模型的委托模式 以避免重写图像核心组件中的逻辑。
请注意以下各行:
@Self
@Via(type = ResourceSuperType.class)
private Image image;
上述注释实例化一个名为的图像对象 image
基于 sling:resourceSuperType
的继承 Card
组件。
@Override
public String getSrc() {
return null != image ? image.getSrc() : null;
}
然后,可以简单地使用 image
用于实施由定义的方法的对象 Image
界面,无需自己编写逻辑。 此技术用于 getSrc()
, getAlt()
、和 getTitle()
.
接下来,实施 initModel()
用于启动私有变量的方法 cardPage
基于的值 cardPath
@PostConstruct
public void initModel() {
if(StringUtils.isNotBlank(cardPath) && pageManager != null) {
cardPage = pageManager.getPage(this.cardPath);
}
}
此 @PostConstruct initModel()
Sling模型初始化时调用,因此这是一个很好的机会来初始化模型中其他方法可能使用的对象。 此 pageManager
为以下项之一 Java™支持的全局对象 可供Sling模型通过 @ScriptVariable
注释。 此 getPage 方法接受路径并返回AEM 页面 对象;如果路径未指向有效页面,则为null。
这会初始化 cardPage
变量,其他新方法使用该变量返回有关底层链接页面的数据。
查看已映射到保存的“创作”对话框的JCR属性的全局变量。 此 @ValueMapValue
批注用于自动执行映射。
@ValueMapValue
private String cardPath;
@ValueMapValue
private String ctaText;
@ValueMapValue
private boolean titleFromPage;
@ValueMapValue
private String cardTitle;
这些变量用于实现的其他方法 Card.java
界面。
实施中定义的其他方法 Card.java
界面:
@Override
public String getCtaLinkURL() {
if(cardPage != null) {
return cardPage.getPath() + ".html";
}
return null;
}
@Override
public String getCtaText() {
return ctaText;
}
@Override
public Calendar getCardLastModified() {
if(cardPage != null) {
return cardPage.getLastModified();
}
return null;
}
@Override
public String getCardTitle() {
if(titleFromPage) {
return cardPage != null ? cardPage.getTitle() : null;
}
return cardTitle;
}
您可以查看 在此处完成CardImpl.java.
打开终端窗口,将更新仅部署到 core
模块使用Maven autoInstallBundle
配置文件来自 core
目录。
$ cd core/
$ mvn clean install -PautoInstallBundle
如果使用 AEM 6.x 添加 classic
个人资料。
在以下位置查看JSON模型响应: http://localhost:4502/content/wknd-spa-angular/us/en.model.json 并搜索 wknd-spa-angular/components/card
:
"card": {
"ctaText": "Read More",
"cardTitle": "Page 1",
"title": "Woman chillaxing with river views in Australian bushland",
"src": "/content/wknd-spa-angular/us/en/home/_jcr_content/root/responsivegrid/card.coreimg.jpeg/1595190732886/adobestock-216674449.jpeg",
"alt": "Female sitting on a large rock relaxing in afternoon dappled light the Australian bushland with views over the river",
"cardLastModified": 1591360492414,
"ctaLinkURL": "/content/wknd-spa-angular/us/en/home/page-1.html",
":type": "wknd-spa-angular/components/card"
}
请注意,更新“ ”中的方法后,会使用其他键/值对更新JSON模型 CardImpl
Sling模型。
现在,JSON模型已填充以下对象的新属性: ctaLinkURL
, ctaText
, cardTitle
、和 cardLastModified
我们可以更新Angular组件以显示这些内容。
返回IDE并打开 ui.frontend
模块。 (可选)从新的终端窗口启动webpack开发服务器以实时查看更改:
$ cd ui.frontend
$ npm install
$ npm start
打开 card.component.ts
在 ui.frontend/src/app/components/card/card.component.ts
. 添加其他 @Input
用于捕获新模型的注释:
export class CardComponent implements OnInit {
@Input() src: string;
@Input() alt: string;
@Input() title: string;
+ @Input() cardTitle: string;
+ @Input() cardLastModified: number;
+ @Input() ctaLinkURL: string;
+ @Input() ctaText: string;
添加以下方法:检查行动号召是否准备就绪,并根据 cardLastModified
输入:
export class CardComponent implements OnInit {
...
get hasCTA(): boolean {
return this.ctaLinkURL && this.ctaLinkURL.trim().length > 0 && this.ctaText && this.ctaText.trim().length > 0;
}
get lastModifiedDate(): string {
const lastModifiedDate = this.cardLastModified ? new Date(this.cardLastModified) : null;
if (lastModifiedDate) {
return lastModifiedDate.toLocaleDateString();
}
return null;
}
...
}
打开 card.component.html
并添加以下标记以显示标题、行动要求和上次修改日期:
<div class="card" *ngIf="hasContent">
<app-image class="card__image" [src]="src" [alt]="alt" [title]="title"></app-image>
<div class="card__content">
<h2 class="card__title">
{{cardTitle}}
<span class="card__lastmod" *ngIf="lastModifiedDate">{{lastModifiedDate}}</span>
</h2>
<div class="card__action-container" *ngIf="hasCTA">
<a [routerLink]="ctaLinkURL" class="card__action-link" [title]="ctaText">
{{ctaText}}
</a>
</div>
</div>
</div>
已在添加Sass规则 card.component.scss
要设置标题的样式,请行动要求和上次修改日期。
您可以查看已完成的 在此处Angular卡组件代码.
使用Maven从项目的根目录将全部更改部署到AEM:
$ cd aem-guides-wknd-spa
$ mvn clean install -PautoInstallSinglePackage
导航到 http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html 要查看更新的组件,请执行以下操作:
您应该能够重新创作现有内容以创建类似于以下内容的页面:
恭喜,您已了解如何扩展AEM组件以及Sling模型和对话框如何与JSON模型一起使用。
您始终可以在以下位置查看完成的代码 GitHub 或通过切换到分行在本地签出代码 Angular/extend-component-solution
.