將SPA元件對應至AEM元件 map-components

瞭解如何使用AEM SPA Editor JS SDK將Angular元件對應至Adobe Experience Manager (AEM)元件。 元件對應可讓使用者在SPA SPA編輯器中對AEM元件進行動態更新,類似於傳統的AEM編寫。

本章更深入地探討AEM JSON模型API,以及如何將AEM元件公開的JSON內容作為prop自動插入到Angular元件中。

目標

  1. 瞭解如何將AEM元件對應至SPA元件。
  2. 瞭解​ Container ​元件與​ Content ​元件之間的差異。
  3. 建立對應至現有AEM元件的新Angular元件。

您將建置的內容

本章將檢查提供的Text SPA元件如何對應至AEM Text元件。 已建立可在SPA中使用並在AEM中編寫的新Image SPA元件。 配置容器 ​和​ 範本編輯器 ​原則的現成功能也會用來建立外觀稍有變化的檢視。

章節範例最終製作

先決條件

檢閱設定本機開發環境所需的工具和指示。

取得程式碼

  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的一部分。 SPA會使用JSON內容,在瀏覽器中執行使用者端。 SPA元件和AEM元件之間會建立1:1對應。

將AEM元件對應到Angular元件的高階概觀

將AEM元件對應到Angular元件的高階概觀

Inspect文字元件

AEM專案原型提供對應至AEM 文字元件Text元件。 這是​ content ​元件的範例,它從AEM轉譯​ 內容

讓我們瞭解元件的運作方式。

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的值公開所編寫文字內容的方法。 在內容為RTF文字的情況下(由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 Editor 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的​ app.module.ts Inspect。

    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 Image元件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並將其放入新建立的​ 影像 ​資料夾。 您可視需要使用自己的影像。

實作影像元件

  1. 如果啟動,請停止​ webpack dev server

  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是決定是否在AEM中根據src屬性是否填入來轉譯作者預留位置的設定。

    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元件,並在​ 全熒幕 ​模式中新增其他段落樣式。

    全熒幕RTF編輯

  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元件的回應式功能和更新的RTF原則來編寫如下的檢視:

    章節範例最終製作

恭喜! congratulations

恭喜,您已瞭解如何將SPA元件對應至AEM元件,並且已實作新的Image元件。 您也有機會探索​ 配置容器 ​的回應式功能。

您一律可以在GitHub上檢視完成的程式碼,或切換至分支Angular/map-components-solution在本機取出程式碼。

後續步驟 next-steps

導覽及路由 — 瞭解如何使用SPA編輯器SDK對應至AEM頁面,以支援SPA中的多個檢視。 動態導覽是使用Angular路由器實作,並新增至現有的Header元件。

額外優點 — 將設定保留到原始檔控制 bonus

在許多情況下,尤其是在AEM專案開始時,將設定(例如範本和相關內容原則)保留到原始檔控制中很有價值。 這可確保所有開發人員都針對相同的內容和設定集,且可確保環境之間有額外的一致性。 一旦專案達到一定的成熟度,管理範本的實務就可以交給特殊的超級使用者群組。

後續幾個步驟將使用Visual Studio Code IDE和VSCode AEM Sync進行,但可能會使用任何工具和您已設定為從AEM本機執行個體​ 提取 ​或​ 匯入 ​內容的任何IDE來執行。

  1. 在Visual Studio Code IDE中,確定您已透過Marketplace擴充功能安裝​ VSCode AEM Sync

    VSCode AEM Sync

  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