将SPA组件映射到AEM组件 map-components

了解如何使用AEM SPA编辑器JS SDK将Angular组件映射到Adobe Experience Manager (AEM)组件。 组件映射使用户能够对AEM SPA编辑器中的SPA组件进行动态更新,这与传统AEM创作类似。

本章更深入地介绍了AEM JSON模型API,以及如何将由AEM组件公开的JSON内容作为prop自动插入到Angular组件中。

目标

  1. 了解如何将AEM组件映射到SPA组件。
  2. 了解​ Container ​组件与​ Content ​组件之间的区别。
  3. 创建映射到现有AEM组件的新Angular组件。

您将构建的内容

本章将检查提供的Text SPA组件如何映射到AEM Text组件。 已创建可在SPA中使用并在SPA中创作的新Image AEM组件。 布局容器 ​和​ 模板编辑器 ​策略的开箱即用功能还将用于创建外观变化稍大的视图。

章节示例最终创作

先决条件

查看设置本地开发环境所需的工具和说明。

获取代码

  1. 通过Git下载本教程的起点:

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd-spa.git
    $ cd aem-guides-wknd-spa
    $ git checkout Angular/map-components-start
    
  2. 使用Maven将代码库部署到本地AEM实例:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage
    

    如果使用AEM 6.x,请添加classic配置文件:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage -Pclassic
    

您始终可以在GitHub上查看完成的代码,或通过切换到分支Angular/map-components-solution在本地签出代码。

映射方法

基本概念是将SPA组件映射到AEM组件。 AEM组件运行服务器端,将内容导出为JSON模型API的一部分。 JSON内容由SPA使用,在浏览器中运行客户端。 在SPA组件和AEM组件之间创建1:1映射。

将AEM组件映射到Angular组件的高级概述

将AEM组件映射到Angular组件的高级概述

Inspect文本组件

AEM项目原型提供了一个映射到AEM 文本组件Text组件。 这是​ content ​组件的示例,该组件渲染来自AEM的​ content

我们来看看组件的工作方式。

Inspect的JSON模型

  1. 在跳转到SPA代码之前,请务必了解AEM提供的JSON模型。 导航到核心组件库并查看文本组件的页面。 核心组件库提供了所有AEM核心组件的示例。

  2. 为以下示例之一选择​ JSON ​选项卡:

    文本JSON模型

    您应该看到三个属性:textrichText:type

    :type是一个保留属性,它列出了AEM组件的sling:resourceType(或路径)。 :type的值用于将AEM组件映射到SPA组件。

    textrichText是对SPA组件公开的其他属性。

Inspect文本组件

  1. 打开新终端并导航到项目中的ui.frontend文件夹。 运行npm install,然后运行npm start以启动​ webpack开发服务器

    code language-shell
    $ cd ui.frontend
    $ npm run start:mock
    

    ui.frontend模块当前设置为使用模拟JSON模型

  2. 您应会看到一个打开到http://localhost:4200/content/wknd-spa-angular/us/en/home.html的新浏览器窗口

    包含模拟内容的 Webpack开发服务器

  3. 在您选择的IDE中,打开WKND SPA的AEM项目。 展开ui.frontend模块并打开ui.frontend/src/app/components/text/text.component.ts下的文件​ text.component.ts

    Text.jsAngular组件Source代码

  4. 第一个要检查的区域是位于第35行的class TextComponent

    code language-js
    export class TextComponent {
        @Input() richText: boolean;
        @Input() text: string;
        @Input() itemName: string;
    
        @HostBinding('innerHtml') get content() {
            return this.richText
            ? this.sanitizer.bypassSecurityTrustHtml(this.text)
            : this.text;
        }
        @HostBinding('attr.data-rte-editelement') editAttribute = true;
    
        constructor(private sanitizer: DomSanitizer) {}
    }
    

    @Input()修饰符用于声明通过映射JSON对象设置的字段,该对象先前已查看。

    @HostBinding('innerHtml') get content()是一种从this.text的值中公开所编写的文本内容的方法。 如果内容是富文本(由this.richText标志确定),将绕过Angular的内置安全性。 angular的DomSanitizer用于“清理”原始HTML并防止跨站点脚本漏洞。 使用@HostBinding修饰器将方法绑定到innerHtml属性。

  5. 接下来,在~第24行检查TextEditConfig

    code language-js
    const TextEditConfig = {
        emptyLabel: 'Text',
        isEmpty: cqModel =>
            !cqModel || !cqModel.text || cqModel.text.trim().length < 1
    };
    

    上述代码负责确定何时在AEM创作环境中呈现占位符。 如果isEmpty方法返回​ true,则会呈现占位符。

  6. 最后,查看第53行以下位置的MapTo调用:

    code language-js
    MapTo('wknd-spa-angular/components/text')(TextComponent, TextEditConfig );
    

    MapTo ​由AEM SPA编辑器JS SDK (@adobe/cq-angular-editable-components)提供。 路径wknd-spa-angular/components/text表示AEM组件的sling:resourceType。 此路径与之前观察到的JSON模型公开的:type匹配。 MapTo ​解析JSON模型响应并将正确的值传递给SPA组件的@Input()变量。

    您可以在ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/text找到AEM Text组件定义。

  7. 通过在ui.frontend/src/mocks/json/en.model.json修改​ en.model.json ​文件来进行试验。

    在第62行~行更新第一个Text值以使用​ H1 ​和​ u ​标记:

    code language-json
        "text": {
            "text": "<h1><u>Hello World!</u></h1>",
            "richText": true,
            ":type": "wknd-spa-angular/components/text"
        }
    

    返回浏览器以查看​ webpack开发服务器 ​提供的效果:

    已更新文本模型

    尝试在​ true / false ​之间切换richText属性以查看正在运行的渲染逻辑。

  8. Inspect text.component.html ​位于ui.frontend/src/app/components/text/text.component.html

    此文件为空,因为组件的全部内容由innerHTML属性设置。

  9. ui.frontend/src/app/app.module.ts上Inspect app.module.ts

    code language-js
    @NgModule({
    imports: [
        BrowserModule,
        SpaAngularEditableComponentsModule,
        AppRoutingModule
    ],
    providers: [ModelManagerService, { provide: APP_BASE_HREF, useValue: '/' }],
    declarations: [AppComponent, TextComponent, PageComponent, HeaderComponent],
    entryComponents: [TextComponent, PageComponent],
    bootstrap: [AppComponent]
    })
    export class AppModule {}
    

    未显式包含​ TextComponent,而是通过AEM SPA编辑器JS SDK提供的​ AEMResponsiveGridComponent ​动态包含。 因此,必须在​ app.module.ts' entryComponents数组中列出。

创建图像组件

接下来,创建映射到AEM 图像组件ImageAngular组件。 Image组件是​ content ​组件的另一个示例。

Inspect和JSON

在跳转到SPA代码之前,请检查AEM提供的JSON模型。

  1. 导航到核心组件库🔗中的图像示例。

    图像核心组件JSON

    srcalttitle的属性用于填充SPA Image组件。

    note note
    NOTE
    其他公开的图像属性(lazyEnabledwidths)允许开发人员创建自适应和延迟加载组件。 本教程中构建的组件非常简单, ​会使用这些高级属性。
  2. 返回到IDE并在ui.frontend/src/mocks/json/en.model.json处打开en.model.json。 由于这是我们项目的新组件,因此我们需要“模拟”图像JSON。

    在第70行,为image模型添加一个JSON条目(不要忘记第二个text_386303036后面的尾随逗号,)并更新:itemsOrder数组。

    code language-json
    ...
    ":items": {
                ...
                "text_386303036": {
                    "text": "<p>A new text component.</p>\r\n",
                    "richText": true,
                    ":type": "wknd-spa-angular/components/text"
                    },
                "image": {
                    "alt": "Rock Climber in New Zealand",
                    "title": "Rock Climber in New Zealand",
                    "src": "/mocks/images/adobestock-140634652.jpeg",
                    ":type": "wknd-spa-angular/components/image"
                }
            },
            ":itemsOrder": [
                "text",
                "text_386303036",
                "image"
            ],
    

    该项目在/mock-content/adobestock-140634652.jpeg处包含一个与​ webpack开发服务器 ​一起使用的示例图像。

    您可以在此处🔗查看完整的en.model.json。

  3. 添加组件要显示的照片库。

    ui.frontend/src/mocks下创建名为​ 图像 ​的新文件夹。 下载adobestock-140634652.jpeg并将其放入新创建的​ images ​文件夹中。 如果需要,您可以随意使用您自己的图像。

实施图像组件

  1. 如果启动,请停止​ webpack开发服务器

  2. 通过从ui.frontend文件夹中运行AngularCLI ng generate component命令创建新的图像组件:

    code language-shell
    $ ng generate component components/image
    
  3. 在IDE中,打开位于ui.frontend/src/app/components/image/image.component.ts的​ image.component.ts ​并按照以下方式更新:

    code language-js
    import {Component, Input, OnInit} from '@angular/core';
    import {MapTo} from '@adobe/cq-angular-editable-components';
    
    const ImageEditConfig = {
    emptyLabel: 'Image',
    isEmpty: cqModel =>
        !cqModel || !cqModel.src || cqModel.src.trim().length < 1
    };
    
    @Component({
    selector: 'app-image',
    templateUrl: './image.component.html',
    styleUrls: ['./image.component.scss']
    })
    export class ImageComponent implements OnInit {
    
    @Input() src: string;
    @Input() alt: string;
    @Input() title: string;
    
    constructor() { }
    
    get hasImage() {
        return this.src && this.src.trim().length > 0;
    }
    
    ngOnInit() { }
    }
    
    MapTo('wknd-spa-angular/components/image')(ImageComponent, ImageEditConfig);
    

    ImageEditConfig是一种配置,用于根据是否填充了src属性确定是否在AEM中呈现作者占位符。

    srcalttitle@Input()是从JSON API映射的属性。

    hasImage()是将确定是否应渲染图像的方法。

    MapTo将SPA组件映射到位于ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image的AEM组件。

  4. 打开​ image.component.html ​并按如下方式更新:

    code language-html
    <ng-container *ngIf="hasImage">
        <img class="image" [src]="src" [alt]="alt" [title]="title"/>
    </ng-container>
    

    如果hasImage返回​ true,这将呈现<img>元素。

  5. 打开​ image.component.scss ​并按如下方式更新:

    code language-scss
    :host-context {
        display: block;
    }
    
    .image {
        margin: 1rem 0;
        width: 100%;
        border: 0;
    }
    
    note note
    NOTE
    :host-context规则是​ 关键,AEM SPA编辑器占位符才能正常工作。 所有打算在SPA页面编辑器中创作的AEM组件至少都需要此规则。
  6. 打开app.module.ts并将ImageComponent添加到entryComponents数组:

    code language-js
    entryComponents: [TextComponent, PageComponent, ImageComponent],
    

    TextComponent一样,ImageComponent也是动态加载的,必须包含在entryComponents数组中。

  7. 启动​ webpack开发服务器 ​以查看ImageComponent渲染。

    code language-shell
    $ npm run start:mock
    

    图像已添加到模拟

    图像已添加到SPA

    note note
    NOTE
    附加质询:实施新方法以将title的值显示为图像下方的标题。

在AEM中更新策略

ImageComponent组件仅在​ webpack开发服务器 ​中可见。 接下来,将更新的SPA部署到AEM并更新模板策略。

  1. 停止​ webpack开发服务器,并从项目的​ ​中,使用您的Maven技能将更改部署到AEM:

    code language-shell
    $ cd aem-guides-wknd-spa
    $ mvn clean install -PautoInstallSinglePackage
    
  2. 从AEM开始屏幕导航到​ 工具 > 模板 > WKND SPAAngular

    选择并编辑​ SPA页面

    编辑SPA页面模板

  3. 选择​ 布局容器 ​并单击它的​ 策略 ​图标以编辑策略:

    布局容器策略

  4. 在​ 允许的组件 > WKND SPAAngular — 内容 >下,检查​ 图像 ​组件:

    已选择 图像组件

    在​ 默认组件 > 添加映射 ​下,并选择​ 图像 — WKND SPAAngular- Content ​组件:

    设置默认组件

    输入image/*的​ MIME类型

    单击​ 完成 ​以保存策略更新。

  5. 在​ 布局容器 ​中,单击​ 文本 ​组件的​ 策略 ​图标:

    文本组件策略图标

    创建名为​ WKND SPA Text ​的新策略。 在​ 插件 > 格式 >下,选中所有框以启用其他格式选项:

    启用RTE格式

    在​ 插件 > 段落样式 >下,选中​ 启用段落样式 ​的框:

    启用段落样式

    单击​ 完成 ​以保存策略更新。

  6. 导航到​ 主页 http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html

    您还应该能够编辑Text组件并在​ 全屏 ​模式下添加其他段落样式。

    全屏富文本编辑

  7. 您还应该能够从​ 资产查找器 ​中拖放图像:

    拖放图像

  8. 通过AEM Assets添加您自己的映像,或者为标准WKND引用站点安装完成的代码库。 WKND引用站点包含可在WKND SPA上重复使用的许多图像。 可以使用AEM包管理器安装包。

    包管理器安装wknd.all

Inspect布局容器

AEM SPA编辑器SDK自动提供对​ 布局容器 ​的支持。 名称指示的​ 布局容器 ​是​ 容器 ​组件。 容器组件是接受JSON结构的组件,该结构表示​ 其他 ​组件并动态实例化它们。

让我们进一步检查布局容器。

  1. 在IDE中,打开ui.frontend/src/app/components/responsive-grid处的​ responsive-grid.component.ts

    code language-js
    import { AEMResponsiveGridComponent,MapTo } from '@adobe/cq-angular-editable-components';
    
    MapTo('wcm/foundation/components/responsivegrid')(AEMResponsiveGridComponent);
    

    AEMResponsiveGridComponent是作为AEM SPA Editor SDK的一部分实现的,并通过import-components包含在项目中。

  2. 在浏览器中导航到http://localhost:4502/content/wknd-spa-angular/us/en.model.json

    JSON模型API — 响应式网格

    布局容器 ​组件具有wcm/foundation/components/responsivegridsling:resourceType,并且被SPA编辑器使用:type属性识别,就像TextImage组件一样。

    SPA编辑器中提供了使用布局模式重新调整组件大小的相同功能。

  3. 返回到http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html。 添加其他​ 图像 ​组件,然后尝试使用​ 布局 ​选项重新调整其大小:

    使用布局模式重新调整图像大小

  4. 重新打开JSON模型http://localhost:4502/content/wknd-spa-angular/us/en.model.json并观察作为JSON一部分的columnClassNames

    列类名

    类名aem-GridColumn--default--4指示组件应基于12列网格为4列宽。 有关响应式网格的更多详细信息见此处

  5. 返回到IDE,在ui.apps模块中ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/clientlibs/clientlib-grid处定义了客户端库。 打开文件less/grid.less

    此文件确定​ 布局容器 ​使用的断点(defaulttabletphone)。 此文件将根据项目规范进行自定义。 当前断点设置为1200px650px

  6. 您应该能够使用Text组件的响应式功能和更新的富文本策略来创作类似于以下内容的视图:

    章节示例最终创作

恭喜! congratulations

恭喜,您已了解如何将SPA组件映射到AEM组件,并且实施了新的Image组件。 您还有机会探索​ 布局容器 ​的响应式功能。

您始终可以在GitHub上查看完成的代码,或通过切换到分支Angular/map-components-solution在本地签出代码。

后续步骤 next-steps

导航和路由 — 了解如何使用SPA编辑器SDK映射到AEM页面,从而支持SPA中的多个视图。 动态导航使用Angular路由器实现,并添加到现有的报头组件中。

额外练习 — 将配置保留到源代码管理 bonus

在许多情况下,尤其是在AEM项目开始时,将配置(如模板和相关内容策略)保留到源代码控制中非常有用。 这可确保所有开发人员都针对同一组内容和配置工作,并可确保环境之间具有额外的一致性。 一旦项目达到一定的成熟度,管理模板的操作就可以交给一组特殊的超级用户。

接下来的几个步骤将使用Visual Studio Code IDE和VSCode AEM Sync执行,但可以使用任何工具和您已配置为从AEM的本地实例​ 提取 ​或​ 导入 ​内容的任何IDE执行。

  1. 在Visual Studio Code IDE中,确保已通过Marketplace扩展安装​ VSCode AEM Sync

    VSCode AEM同步

  2. 在项目资源管理器中展开​ ui.content ​模块并导航到/conf/wknd-spa-angular/settings/wcm/templates

  3. 右键单击 templates文件夹并选择​ 从AEM服务器导入

    VSCode导入模板

  4. 重复导入内容的步骤,但选择位于/conf/wknd-spa-angular/settings/wcm/policies的​ 策略 ​文件夹。

  5. Inspect位于ui.content/src/main/content/META-INF/vault/filter.xmlfilter.xml文件。

    code language-xml
    <!--ui.content filter.xml-->
    <?xml version="1.0" encoding="UTF-8"?>
     <workspaceFilter version="1.0">
         <filter root="/conf/wknd-spa-angular" mode="merge"/>
         <filter root="/content/wknd-spa-angular" mode="merge"/>
         <filter root="/content/dam/wknd-spa-angular" mode="merge"/>
         <filter root="/content/experience-fragments/wknd-spa-angular" mode="merge"/>
     </workspaceFilter>
    

    filter.xml文件负责识别与包一起安装的节点的路径。 请注意每个筛选器上的mode="merge",这表示现有内容将不会被修改,而是只会添加新内容。 由于内容作者可能正在更新这些路径,因此代码部署​ ​覆盖内容非常重要。 有关使用筛选器元素的更多详细信息,请参阅FileVault文档

    比较ui.content/src/main/content/META-INF/vault/filter.xmlui.apps/src/main/content/META-INF/vault/filter.xml以了解每个模块管理的不同节点。

recommendation-more-help
e25b6834-e87f-4ff3-ba56-4cd16cdfdec4