將SPA元件對應至AEM元件

了解如何使用AEM SPA Editor 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. 建立新的Angular元件,將其映射至現有的AEM元件。

您將建置的

本章將檢查提供的Text SPA元件如何對應至AEM Text元件。 將建立新的Image SPA元件,可在SPA中使用並在AEM中製作。 佈局容器​和​模板編輯器​策略的現成功能也將用於建立外觀更多樣的視圖。

章節範例最終製作

必備條件

查看設定本地開發環境所需的工具和說明。

取得程式碼

  1. 透過Git下載本教學課程的起始點:

    $ 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例項:

    $ mvn clean install -PautoInstallSinglePackage
    

    如果使用AEM 6.x新增classic設定檔:

    $ 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 the Text Component

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

讓我們查看元件的運作方式。

Inspect JSON模型

  1. 在跳入SPA程式碼之前,請務必了解AEM提供的JSON模型。 導覽至核心元件庫並檢視文字元件的頁面。 核心元件程式庫提供所有AEM核心元件的範例。

  2. 選取其中一個範例的​JSON​標籤:

    文字JSON模型

    您應該會看到三個屬性:textrichText:type

    :type 是保留屬性,會列 sling:resourceType 出AEM元件的(或路徑)。:type值可用來將AEM元件對應至SPA元件。

    textrichText 是將公開給SPA元件的其他屬性。

Inspect the Text元件

  1. 開啟新終端機,並導覽至專案內的ui.frontend資料夾。 運行npm install,然後運行npm start以啟動​Webpack開發伺服器:

    $ 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元件原始碼

  4. 要檢查的第一個區域是~35行的class TextComponent:

    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() decorator可用來宣告哪些欄位是透過已對應JSON物件(已先審閱)設定的。

    @HostBinding('innerHtml') get content() 是從的值公開製作的文字內容的方 this.text法。如果內容為RTF(由this.richText標幟決定),則會略過Angular的內建安全性。 Angular的DomSanitizer用於「拖曳」原始HTML並防止跨網站指令碼漏洞。 該方法使用@HostBinding解碼器綁定到innerHtml屬性。

  5. 接下來,在~24行檢查TextEditConfig :

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

    上述程式碼負責決定何時在AEM製作環境中呈現預留位置。 如果isEmpty方法傳回​true,則會呈現預留位置。

  6. 最後,查看~line 53處的MapTo呼叫:

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

    ​AEM SPA Editor JS SDK(@adobe/cq-angular-editable-components)提供的MapTo。路徑wknd-spa-angular/components/text代表AEM元件的sling:resourceType。 此路徑與先前觀察到的JSON模型公開的:type相符。 ​MapTo解析JSON模型回應,並將正確值傳 @Input() 遞至SPA元件的變數。

    您可以在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​檔案以進行實驗。

    ~line 62會更新第一個Text值,以使用​H1​和​u​標籤:

        "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 at ui.frontend/src/app/components/text/text.component.html

    此檔案為空,因為元件的整個內容將由innerHTML屬性設定。

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

    @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 Editor JS SDK提供的​AEMResponsiveGridComponent​動態包含。 因此,必須列在​app.module.ts` entryComponents陣列中。

建立影像元件

接下來,建立映射到AEM 影像元件ImageAngular元件。 Image元件是​content​元件的另一個示例。

Inspect JSON

在跳入SPA程式碼之前,請檢查AEM提供的JSON模型。

  1. 導覽至核心元件程式庫🔗中的影像範例。

    影像核心元件JSON

    srcalttitle的屬性將用於填入SPA Image元件。

    注意

    有其他公開的影像屬性(lazyEnabled, widths)可讓開發人員建立最適化和延遲載入元件。 本教學課程中建置的元件將會很簡單,並且​not​會使用這些進階屬性。

  2. 返回IDE,在ui.frontend/src/mocks/json/en.model.json處開啟en.model.json。 由於這是專案的全新元件,因此我們需要「模擬」影像JSON。

    在~70行中,為image模型(別忘了第二個text_386303036後面的尾隨逗號,)新增JSON項目,並更新:itemsOrder陣列。

    ...
    ":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下方建立名為​images​的新資料夾。 下載adobestock-140634652.jpeg並將其置於新建立的​images​資料夾中。 如有需要,歡迎使用您自己的影像。

實作影像元件

  1. 如果啟動,請停止​Webpack開發伺服器

  2. 通過從ui.frontend資料夾內運行AngularCLI ng generate component命令建立新的映像元件:

    $ ng generate component components/image
    
  3. 在IDE中,開啟​image.component.ts(ui.frontend/src/app/components/image/image.component.ts),然後按如下方式更新:

    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 者預留位置。

    @Input()srcalttitle 從JSON API對應的屬性。

    hasImage() 是可判斷是否應轉譯影像的方法。

    MapTo 將SPA元件對應至位於的AEM元件 ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image

  4. 開啟​image.component.html,然後依照以下方式更新:

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

    如果hasImage傳回​true,則會呈現<img>元素。

  5. 開啟​image.component.scss,然後依照以下方式更新:

    :host-context {
        display: block;
    }
    
    .image {
        margin: 1rem 0;
        width: 100%;
        border: 0;
    }
    
    注意

    :host-context規則為​critical ,AEM SPA編輯器預留位置可正確運作。 所有打算在AEM頁面編輯器中製作的SPA元件至少都需要此規則。

  6. 開啟app.module.ts並將ImageComponent新增至entryComponents陣列:

    entryComponents: [TextComponent, PageComponent, ImageComponent],
    

    TextComponent一樣,ImageComponent是動態載入的,且必須包含在entryComponents陣列中。

  7. 啟動​Webpack開發伺服器​以查看ImageComponent呈現。

    $ npm run start:mock
    

    模擬中新增的影像

    已新增影像至SPA

    注意

    獎金挑戰:實作新方法,將的值顯示 title 為影像下方的註解。

更新AEM中的原則

ImageComponent元件僅顯示在​Webpack開發伺服器​中。 接著,將更新的SPA部署至AEM並更新範本原則。

  1. 停止​webpack開發伺服器,並從專案的​root,使用Maven技能將變更部署至AEM:

    $ cd aem-guides-wknd-spa
    $ mvn clean install -PautoInstallSinglePackage
    
  2. 從「AEM開始」螢幕導覽至「工具 > 範本 > WKND SPAAngular」。

    選擇並編輯​SPA Page:

    編輯SPA頁面範本

  3. 選擇​佈局容器​並按一下其​policy​表徵圖以編輯策略:

    佈局容器策略

  4. 在「允許的元件」>「WKND SPAAngular — 內容」下,檢查​Image​元件:

    已選取影像元件

    在「預設元件 > 添加映射」下,選擇​影像 — WKND SPAAngular — 內容​元件:

    設定預設元件

    輸入​mime類型(image/*)。

    按一下​Done​以保存策略更新。

  5. 在​佈局容器​中,按一下​Text​元件的​policy​表徵圖:

    文本元件策略表徵圖

    建立名為​WKND SPA Text​的新策略。 在​Plugins > Formatting​下,選中所有框以啟用其他格式選項:

    啟用RTE格式

    在​Plugins > 段落樣式 >下,選中該框以​啟用段落樣式:

    啟用段落樣式

    按一下​Done​以保存策略更新。

  6. 導覽至​Homepage 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結構的元件,這些結構代表​other​元件並以動態方式具現化。

讓我們進一步檢查「版面容器」。

  1. 在IDE中,在ui.frontend/src/app/components/responsive-grid處開啟​responsive-grid.component.ts:

    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編輯器提供使用Layout Mode重新調整元件大小的相同功能。

  3. 返回http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html。 新增其他​Image​元件,並嘗試使用​Layout​選項重新調整元件大小:

    使用「佈局」模式重新調整影像大小

  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原則來製作如下所示的檢視:

    章節範例最終製作

恭喜!

恭喜您,您已學習如何將SPA元件對應至AEM元件,且已實作新的Image元件。 您也可以探索​版面容器​的回應功能。

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

後續步驟

導覽與路由 — 使用SPA Editor SDK對應至AEM頁面,可了解SPA中的多個檢視如何受到支援。動態導航是使用Angular路由器實現的,並添加到現有的標頭元件中。

額外 — 保留原始碼控制的配置

在許多情況下,尤其是在AEM專案開始時,最好將設定(例如範本和相關內容原則)保留到原始碼控制。 這可確保所有開發人員針對相同的內容和設定組合工作,並可確保環境之間的額外一致性。 一旦項目達到一定的成熟程度,管理模板的做法就可以交給特定的一組電源用戶。

接下來的幾個步驟將使用Visual Studio Code IDE和VSCode AEM同步進行,但可能使用您已配置為​pull​或​從AEM的本地實例導入​內容的任何工具和任何IDE來執行。

  1. 在Visual Studio代碼IDE中,確保已通過Marketplace擴展安裝​VSCode AEM同步:

    VSCode AEM同步

  2. 展開「專案總管」中的​ui.content​模組,並導覽至/conf/wknd-spa-angular/settings/wcm/templates

  3. 按一下右 鍵資料 templates 夾,然後選 取「從AEM伺服器匯入」:

    VSCode匯入範本

  4. 重複匯入內容的步驟,但選取位於/conf/wknd-spa-angular/settings/wcm/policies的​policys​資料夾。

  5. Inspect位於ui.content/src/main/content/META-INF/vault/filter.xmlfilter.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以了解每個模組所管理的不同節點。

本頁內容