擴充核心元件 extend-component

瞭解如何擴充與AEM SPA編輯器搭配使用的現有核心元件。 瞭解如何擴充現有元件是一項強大的技術,可自訂和擴充AEM SPA Editor實作的功能。

目標

  1. 使用其他屬性和內容擴充現有的核心元件。
  2. 透過使用瞭解元件繼承的基本知識 sling:resourceSuperType.
  3. 瞭解如何使用 委派模式 以便Sling模型重複使用現有邏輯和功能。

您將建置的內容

在本章中,新增了 Card 元件已建立。 此 Card 元件延伸 影像核心元件 新增其他內容欄位,如「標題」和「號召性用語」按鈕,針對SPA內的其他內容執行Teaser的角色。

卡片元件的最終製作

NOTE
在真實世界的實作中,可能更適合直接使用 Teaser元件 比擴充 影像核心元件 以建立 Card 元件而定。 建議一律使用 核心元件 可能時直接進行。

先決條件

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

取得程式碼

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

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd-spa.git
    $ cd aem-guides-wknd-spa
    $ git checkout Angular/extend-component-start
    
  2. 使用Maven將程式碼庫部署到本機AEM執行個體:

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage
    

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

    code language-shell
    $ mvn clean install -PautoInstallSinglePackage -Pclassic
    
  3. 安裝完成的傳統套件 WKND參考網站. 提供的影像 WKND參考網站 在WKND SPA上重複使用。 套件可使用以下方式安裝: AEM封裝管理員.

    封裝管理員安裝wknd.all

您一律可以於檢視完成的程式碼 GitHub 或切換至分支以在本機簽出程式碼 Angular/extend-component-solution.

Inspect初始卡片實施

章節起始程式碼已提供初始卡片元件。 Inspect是資訊卡實作的起點。

  1. 在您選擇的IDE中,開啟 ui.apps 模組。

  2. 瀏覽至 ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/card 並檢視 .content.xml 檔案。

    卡片元件AEM定義開始

    code language-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影像元件的功能。

  3. Inspect檔案 ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/image/.content.xml

    code language-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影像元件繼承了核心元件影像的功能。

    也稱為 Proxy模式 Sling資源繼承是一種強大的設計模式,可讓子元件繼承功能並在需要時擴充/覆寫行為。 Sling繼承支援多個繼承層級,因此最終支援新的 Card 元件會繼承核心元件影像的功能。

    許多開發團隊都會努力做到自我(請勿重複這點)。 Sling繼承可讓您在AEM中完成此操作。

  4. card 資料夾,開啟檔案 _cq_dialog/.content.xml.

    此檔案是元件對話方塊定義 Card 元件。 如果使用Sling繼承,則可以使用 Sling資源合併 覆蓋或延伸對話方塊部分。 在此範例中,對話方塊中已新增索引標籤,以從作者擷取其他資料並填入卡片元件。

    屬性,例如 sling:orderBefore 允許開發人員選擇插入新標籤或表單欄位的位置。 在此案例中, Text 標籤會插入在 asset 標籤。 若要充分利用Sling Resource Merger,請務必瞭解的原始對話方塊節點結構 影像元件對話方塊.

  5. card 資料夾,開啟檔案 _cq_editConfig.xml. 此檔案指定AEM編寫UI中的拖放行為。 擴充影像元件時,資源型別必須符合元件本身。 檢閱 <parameters> 節點:

    code language-xml
    <parameters
        jcr:primaryType="nt:unstructured"
        sling:resourceType="wknd-spa-angular/components/card"
        imageCrop=""
        imageMap=""
        imageRotate=""/>
    

    大部分的元件不需要 cq:editConfig、影像及影像元件的子系下階專案為例外情況。

  6. 在IDE中切換至 ui.frontend 模組,導覽至 ui.frontend/src/app/components/card

    angular元件開始

  7. Inspect檔案 card.component.ts.

    元件已截斷,無法對應至AEM Card 使用標準的元件 MapTo 函式。

    code language-js
    MapTo('wknd-spa-angular/components/card')(CardComponent, CardEditConfig);
    

    檢閱三項 @Input 的類別中的引數 srcalt、和 title. 這些是AEM元件中對應至Angular元件的預期JSON值。

  8. 開啟檔案 card.component.html

    code language-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 元件需要更新範本原則。

  1. 將入門程式碼部署到AEM的本機執行個體(如果尚未部署):

    code language-shell
    $ cd aem-guides-wknd-spa
    $ mvn clean install -PautoInstallSinglePackage
    
  2. 導覽至SPA頁面範本,網址為 http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.

  3. 更新配置容器的原則以新增 Card 作為允許元件的元件:

    更新配置容器原則

    儲存原則的變更,並觀察 Card 作為允許元件的元件:

    卡片元件作為允許的元件

作者初始卡片元件

接下來,編寫 Card 元件使用AEM SPA編輯器。

  1. 瀏覽至 http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html.

  2. Edit 模式,新增 Card 元件至 Layout Container

    插入新元件

  3. 將影像從資產尋找器拖放至 Card 元件:

    新增影像

  4. 開啟 Card 元件對話方塊並注意已新增 文字 標籤。

  5. 文字 標籤:

    文字元件索引標籤

    卡片路徑 — 在SPA首頁下方選擇頁面。

    CTA文字 - 「瞭解詳情」

    卡片標題 — 留空

    從連結的頁面取得標題 — 勾選核取方塊以指出true。

  6. 更新 資產中繼資料 標籤以新增值 替代文字註解.

    更新對話方塊後,目前沒有其他變更顯示。 若要向Angular元件公開新欄位,我們需要更新的Sling模型 Card 元件。

  7. 開啟新標籤並導覽至 CRXDE-Lite. Inspect下的內容節點 /content/wknd-spa-angular/us/en/home/jcr:content/root/responsivegrid 以尋找 Card 元件內容。

    CRXDE-Lite元件屬性

    觀察該屬性 cardPathctaTexttitleFromPage 會持續顯示對話方塊。

更新卡片Sling模型

若要最終將元件對話方塊中的值公開給Angular元件,我們需要更新為填入JSON的Sling模型 Card 元件。 我們也有機會實作兩種商業邏輯:

  • 如果 titleFromPagetrue,傳回指定的頁面標題 cardPath 否則傳回值 cardTitle textfield.
  • 傳回指定的頁面上次修改日期 cardPath.

返回您選擇的IDE並開啟 core 模組。

  1. 開啟檔案 Card.javacore/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 介面,就像我們在 自訂元件章節.

  2. 將下列方法新增至介面:

    code language-java
    @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元件。

  3. 開啟 CardImpl.java. 此為的實作 Card.java 介面。 為了加速教學課程,已部分解決此實作。 請注意, @Model@Exporter 註解以確保Sling模型能夠透過Sling模型匯出工具序列化為JSON。

    CardImpl.java 也會使用 Sling模型的委派模式 以避免從影像核心元件重寫邏輯。

  4. 請注意下列各行:

    code language-java
    @Self
    @Via(type = ResourceSuperType.class)
    private Image image;
    

    上述註解會具現化名為的影像物件 image 根據 sling:resourceSuperType 的繼承 Card 元件。

    code language-java
    @Override
    public String getSrc() {
        return null != image ? image.getSrc() : null;
    }
    

    然後,您就可以直接使用 image 物件,用來實作由定義的方法 Image 介面,而不需自行撰寫邏輯。 此技巧用於 getSrc()getAlt()、和 getTitle().

  5. 接下來,實作 initModel() 初始化私人變數的方法 cardPage 根據的值 cardPath

    code language-java
    @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 變數,其他新方法會使用此變數傳回基礎連結頁面的相關資料。

  6. 檢閱已對映至作者對話方塊所儲存JCR屬性的全域變數。 此 @ValueMapValue 註解用於自動執行對應。

    code language-java
    @ValueMapValue
    private String cardPath;
    
    @ValueMapValue
    private String ctaText;
    
    @ValueMapValue
    private boolean titleFromPage;
    
    @ValueMapValue
    private String cardTitle;
    

    這些變數可用來實作的其他方法, Card.java 介面。

  7. 實作中定義的其他方法 Card.java 介面:

    code language-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;
    }
    
    note note
    NOTE
    您可以檢視 在這裡完成CardImpl.java.
  8. 開啟終端機視窗,將更新僅部署到 core 使用Maven模組 autoInstallBundle 來自的設定檔 core 目錄。

    code language-shell
    $ cd core/
    $ mvn clean install -PautoInstallBundle
    

    若使用 AEM 6.x 新增 classic 設定檔。

  9. 在以下位置檢視JSON模型回應: http://localhost:4502/content/wknd-spa-angular/us/en.model.json 並搜尋 wknd-spa-angular/components/card

    code language-json
    "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模型。

更新Angular元件

現在JSON模型已填入的新屬性 ctaLinkURLctaTextcardTitle、和 cardLastModified 我們可以更新Angular元件以顯示這些專案。

  1. 返回IDE並開啟 ui.frontend 模組。 您可以選擇從新的終端機視窗啟動webpack開發伺服器,即時檢視變更:

    code language-shell
    $ cd ui.frontend
    $ npm install
    $ npm start
    
  2. 開啟 card.component.tsui.frontend/src/app/components/card/card.component.ts. 新增其他 @Input 用來擷取新模型的註解:

    code language-diff
    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;
    
  3. 新增方法以檢查行動號召是否準備就緒,並根據 cardLastModified 輸入:

    code language-js
    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;
        }
        ...
    }
    
  4. 開啟 card.component.html 並新增下列標籤以顯示標題、行動號召和上次修改日期:

    code language-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>
    

    已在新增銷售規則 card.component.scss 若要設定標題樣式、行動號召和上次修改日期。

    note note
    NOTE
    您可以檢視完成的 將卡片元件程式碼Angular到這裡.
  5. 使用Maven從專案的根將完整變更部署到AEM:

    code language-shell
    $ cd aem-guides-wknd-spa
    $ mvn clean install -PautoInstallSinglePackage
    
  6. 瀏覽至 http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html 若要檢視更新的元件:

    更新AEM中的卡片元件

  7. 您應該能夠重新編寫現有內容以建立類似下列的頁面:

    卡片元件的最終製作

恭喜! congratulations

恭喜,您已瞭解如何擴充AEM元件,以及Sling模型和對話方塊如何搭配JSON模型使用。

您一律可以於檢視完成的程式碼 GitHub 或切換至分支以在本機簽出程式碼 Angular/extend-component-solution.

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