新增導覽和路由 navigation-routing

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

目標

  1. 瞭解使用SPA編輯器時可用的SPA模型路由選項。
  2. 瞭解如何使用 angular路由 以瀏覽SPA的不同檢視。
  3. 實作由AEM頁面階層驅動的動態導覽。

您將建置的內容

本章將導覽功能表新增至現有的 Header 元件。 導覽功能表是由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/navigation-routing-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/navigation-routing-solution.

Inspect HeaderComponent更新 inspect-header

在前幾章中, HeaderComponent 元件是透過新增為純Angular元件 app.component.html. 在本章中, HeaderComponent 元件會從應用程式移除,並透過以下方式新增: 範本編輯器. 這可讓使用者設定 HeaderComponent 從AEM中。

NOTE
程式碼庫已進行數個CSS和JavaScript更新,以便開始本章的編寫。 專注於核心概念,而非 全部 將會討論其中部分程式碼變更。 您可以檢視完整變更 此處.
  1. 在您選擇的IDE中,開啟本章的SPA入門專案。

  2. ui.frontend 模組檢查檔案 header.component.ts 於: ui.frontend/src/app/components/header/header.component.ts.

    已進行數個更新,包括新增 HeaderEditConfigMapTo 啟用元件對應至AEM元件的方式 wknd-spa-angular/components/header.

    code language-js
    /* header.component.ts */
    ...
    const HeaderEditConfig = {
        ...
    };
    
    @Component({
    selector: 'app-header',
    templateUrl: './header.component.html',
    styleUrls: ['./header.component.scss']
    })
    export class HeaderComponent implements OnInit {
    @Input() items: object[];
        ...
    }
    ...
    MapTo('wknd-spa-angular/components/header')(withRouter(Header), HeaderEditConfig);
    

    請注意 @Input() 註解 items. items 將包含從AEM傳入的導覽物件陣列。

  3. ui.apps 模組檢查AEM的元件定義 Header 元件: ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/components/header/.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="Header"
        sling:resourceSuperType="wknd-spa-angular/components/navigation"
        componentGroup="WKND SPA Angular - Structure"/>
    

    AEM Header 元件將繼承的所有功能 導覽核心元件 透過 sling:resourceSuperType 屬性。

將HeaderComponent新增至SPA範本 add-header-template

  1. 開啟瀏覽器並登入AEM, http://localhost:4502/. 起始程式碼基底應該已經部署。

  2. 導覽至 SPA頁面範本http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html.

  3. 選取最外層 根配置容器 並按一下 原則 圖示。 請小心 以選取 配置容器 已解除製作鎖定。

    選取根配置容器原則圖示

  4. 複製目前的原則並建立名為的新原則 SPA結構

    SPA結構原則

    允許的元件 > 一般 >選取 配置容器 元件。

    允許的元件 > WKND SPAANGULAR — 結構 >選取 頁首 元件:

    選取標題元件

    允許的元件 > WKND SPAANGULAR — 內容 >選取 影像文字 元件。 您總共應選取4個元件。

    按一下「完成」以儲存變更。

  5. 重新整理 頁面。 新增 頁首 元件在解鎖前面 配置容器

    將標題元件新增至範本

  6. 選取 頁首 元件並按一下其 原則 圖示可編輯原則。

    按一下標頭原則

  7. 使用建立新原則 原則標題"WKND SPA標題".

    屬性

    • 設定 導覽根目錄/content/wknd-spa-angular/us/en.
    • 設定 排除根層級1.
    • 取消核取 收集所有子頁面.
    • 設定 導覽結構深度3.

    設定標頭原則

    這會收集下方2個層級的導覽 /content/wknd-spa-angular/us/en.

  8. 儲存變更後,您應會看到已填入的 Header 做為範本的一部分:

    填入的標頭元件

建立子頁面

接著,在AEM中建立其他頁面,做為SPA中的不同檢視。 我們也會檢查AEM所提供JSON模型的階層結構。

  1. 導覽至 網站 主控台: http://localhost:4502/sites.html/content/wknd-spa-angular/us/en/home. 選取 WKND SPAAngular首頁 並按一下 建立 > 頁面

    建立新頁面

  2. 範本 選取 SPA頁面. 在 屬性 進入 "第1頁" 針對 標題"page-1" 作為名稱。

    輸入初始頁面屬性

    按一下 建立 而在對話方塊快顯視窗中,按一下 開啟 以在AEM SPA編輯器中開啟頁面。

  3. 新增 文字 元件至主要 配置容器. 編輯元件並輸入文字: "第1頁" 使用RTE和 H1 元素(您必須進入全熒幕模式才能變更段落元素)

    範例內容頁面1

    您可以隨意新增其他內容,例如影像。

  4. 返回AEM Sites主控台並重複上述步驟,建立第二個頁面,名為 「第2頁」 做為同層級 第1頁. 新增內容至 第2頁 以便輕鬆識別。

  5. 最後,建立第三頁, 「第3頁」子項第2頁. 完成後,網站階層應如下所示:

    範例網站階層

  6. 在新標籤中,開啟AEM提供的JSON模型API: http://localhost:4502/content/wknd-spa-angular/us/en.model.json. SPA首次載入時會請求此JSON內容。 外部結構如下所示:

    code language-json
    {
    "language": "en",
    "title": "en",
    "templateName": "spa-app-template",
    "designPath": "/libs/settings/wcm/designs/default",
    "cssClassNames": "spa page basicpage",
    ":type": "wknd-spa-angular/components/spa",
    ":items": {},
    ":itemsOrder": [],
    ":hierarchyType": "page",
    ":path": "/content/wknd-spa-angular/us/en",
    ":children": {
        "/content/wknd-spa-angular/us/en/home": {},
        "/content/wknd-spa-angular/us/en/home/page-1": {},
        "/content/wknd-spa-angular/us/en/home/page-2": {},
        "/content/wknd-spa-angular/us/en/home/page-2/page-3": {}
        }
    }
    

    :children 您應該會看見每個已建立頁面的專案。 所有頁面的內容都在此初始JSON請求中。 一旦導覽路由實作後,SPA的後續檢視就會快速載入,因為內容在使用者端即可使用。

    載入是不明智的 全部 SPA內容於初始JSON請求中的變數,因為這會減慢初始頁面載入的速度。 接下來,讓我們看看如何收集頁面的階層式深度。

  7. 導覽至 SPA根目錄 範本位於: http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-app-template/structure.html.

    按一下 頁面屬性功能表 > 頁面原則

    開啟SPA Root的頁面原則

  8. SPA根目錄 範本有一個額外的 階層結構 索引標籤來控制收集的JSON內容。 此 結構深度 決定網站階層中要多深才能收集下方的子頁面 . 您也可以使用 結構模式 根據規則運算式篩選掉其他頁面的欄位。

    更新 結構深度"2"

    更新結構深度

    按一下 完成 儲存原則的變更。

  9. 重新開啟JSON模型 http://localhost:4502/content/wknd-spa-angular/us/en.model.json.

    code language-json
    {
    "language": "en",
    "title": "en",
    "templateName": "spa-app-template",
    "designPath": "/libs/settings/wcm/designs/default",
    "cssClassNames": "spa page basicpage",
    ":type": "wknd-spa-angular/components/spa",
    ":items": {},
    ":itemsOrder": [],
    ":hierarchyType": "page",
    ":path": "/content/wknd-spa-angular/us/en",
    ":children": {
        "/content/wknd-spa-angular/us/en/home": {},
        "/content/wknd-spa-angular/us/en/home/page-1": {},
        "/content/wknd-spa-angular/us/en/home/page-2": {}
        }
    }
    

    請注意 第3頁 路徑已移除: /content/wknd-spa-angular/us/en/home/page-2/page-3 從初始JSON模型。

    稍後,我們將觀察AEM SPA Editor SDK如何以動態方式載入其他內容。

實作導覽

接下來,使用新的來實施導覽功能表 NavigationComponent. 我們可以直接在中新增程式碼 header.component.html 但避免大型元件是較好的作法。 請改為實作 NavigationComponent 日後可能會重複使用。

  1. 檢閱AEM公開的JSON Header 元件於 http://localhost:4502/content/wknd-spa-angular/us/en.model.json

    code language-json
    ...
    "header": {
        "items": [
        {
        "level": 0,
        "active": true,
        "path": "/content/wknd-spa-angular/us/en/home",
        "description": null,
        "url": "/content/wknd-spa-angular/us/en/home.html",
        "lastModified": 1589062597083,
        "title": "WKND SPA Angular Home Page",
        "children": [
                {
                "children": [],
                "level": 1,
                "active": false,
                "path": "/content/wknd-spa-angular/us/en/home/page-1",
                "description": null,
                "url": "/content/wknd-spa-angular/us/en/home/page-1.html",
                "lastModified": 1589429385100,
                "title": "Page 1"
                },
                {
                "level": 1,
                "active": true,
                "path": "/content/wknd-spa-angular/us/en/home/page-2",
                "description": null,
                "url": "/content/wknd-spa-angular/us/en/home/page-2.html",
                "lastModified": 1589429603507,
                "title": "Page 2",
                "children": [
                    {
                    "children": [],
                    "level": 2,
                    "active": false,
                    "path": "/content/wknd-spa-angular/us/en/home/page-2/page-3",
                    "description": null,
                    "url": "/content/wknd-spa-angular/us/en/home/page-2/page-3.html",
                    "lastModified": 1589430413831,
                    "title": "Page 3"
                    }
                ],
                }
            ]
            }
        ],
    ":type": "wknd-spa-angular/components/header"
    

    AEM頁面的階層特性使用JSON進行建模,可用來填入導覽功能表。 記住 Header 元件繼承了 導覽核心元件 透過JSON公開的內容會自動對應至Angular @Input 註解。

  2. 開啟新的終端機視窗並導覽至 ui.frontend SPA專案的資料夾。 建立新的 NavigationComponent 使用AngularCLI工具:

    code language-shell
    $ cd ui.frontend
    $ ng generate component components/navigation
    CREATE src/app/components/navigation/navigation.component.scss (0 bytes)
    CREATE src/app/components/navigation/navigation.component.html (25 bytes)
    CREATE src/app/components/navigation/navigation.component.spec.ts (656 bytes)
    CREATE src/app/components/navigation/navigation.component.ts (286 bytes)
    UPDATE src/app/app.module.ts (2032 bytes)
    
  3. 接下來,建立名為的類別 NavigationLink 在新建立的中使用AngularCLI components/navigation 目錄:

    code language-shell
    $ cd src/app/components/navigation/
    $ ng generate class NavigationLink
    CREATE src/app/components/navigation/navigation-link.spec.ts (187 bytes)
    CREATE src/app/components/navigation/navigation-link.ts (32 bytes)
    
  4. 返回您選擇的IDE並在以下位置開啟檔案: navigation-link.ts/src/app/components/navigation/navigation-link.ts.

    開啟navigation-link.ts檔案

  5. 填入 navigation-link.ts ,其功能如下:

    code language-js
    export class NavigationLink {
    
        title: string;
        path: string;
        url: string;
        level: number;
        children: NavigationLink[];
        active: boolean;
    
        constructor(data) {
            this.path = data.path;
            this.title = data.title;
            this.url = data.url;
            this.level = data.level;
            this.active = data.active;
            this.children = data.children.map( item => {
                return new NavigationLink(item);
            });
        }
    }
    

    這是代表個別導覽連結的簡單類別。 在預期的類別建構函式中 data 作為從AEM傳入的JSON物件。 此類別同時用於 NavigationComponentHeaderComponent 以輕鬆填入導覽結構。

    不會執行資料轉換,此類別主要是建立以強式輸入JSON模型。 請注意 this.children 是型別為 NavigationLink[] 而且建構函式會遞回建立 NavigationLink 中每個專案的物件 children 陣列。 召回的JSON模型 Header 為階層式。

  6. 開啟檔案 navigation-link.spec.ts. 這是的測試檔案 NavigationLink 類別。 以下列專案更新它:

    code language-js
    import { NavigationLink } from './navigation-link';
    
    describe('NavigationLink', () => {
        it('should create an instance', () => {
            const data = {
                children: [],
                level: 1,
                active: false,
                path: '/content/wknd-spa-angular/us/en/home/page-1',
                description: null,
                url: '/content/wknd-spa-angular/us/en/home/page-1.html',
                lastModified: 1589429385100,
                title: 'Page 1'
            };
            expect(new NavigationLink(data)).toBeTruthy();
        });
    });
    

    請注意 const data 遵循先前針對單一連結檢查的相同JSON模型。 這遠非強大的單位測試,但應該足以測試下列的建構函式: NavigationLink.

  7. 開啟檔案 navigation.component.ts. 以下列專案更新它:

    code language-js
    import { Component, OnInit, Input } from '@angular/core';
    import { NavigationLink } from './navigation-link';
    
    @Component({
    selector: 'app-navigation',
    templateUrl: './navigation.component.html',
    styleUrls: ['./navigation.component.scss']
    })
    export class NavigationComponent implements OnInit {
    
        @Input() items: object[];
    
        constructor() { }
    
        get navigationLinks(): NavigationLink[] {
    
            if (this.items && this.items.length > 0) {
                return this.items.map(item => {
                    return new NavigationLink(item);
                });
            }
    
            return null;
        }
    
        ngOnInit() {}
    
    }
    

    NavigationComponent 預期一個 object[] 已命名 items 這是來自AEM的JSON模型。 此類別會公開單一方法 get navigationLinks() 會傳回陣列 NavigationLink 物件。

  8. 開啟檔案 navigation.component.html 並以下列專案更新:

    code language-html
    <ul *ngIf="navigationLinks && navigationLinks.length > 0" class="navigation__group">
        <ng-container *ngTemplateOutlet="recursiveListTmpl; context:{ links: navigationLinks }"></ng-container>
    </ul>
    

    這會產生一個初始 <ul> 並呼叫 get navigationLinks() 方法來源 navigation.component.ts. 一個 <ng-container> 用於呼叫範本,命名為 recursiveListTmpl 並傳遞給 navigationLinks 作為變數,名為 links.

    新增 recursiveListTmpl 下一步:

    code language-html
    <ng-template #recursiveListTmpl let-links="links">
        <li *ngFor="let link of links" class="{{'navigation__item navigation__item--' + link.level}}">
            <a [routerLink]="link.url" class="navigation__item-link" [title]="link.title" [attr.aria-current]="link.active">
                {{link.title}}
            </a>
            <ul *ngIf="link.children && link.children.length > 0">
                <ng-container *ngTemplateOutlet="recursiveListTmpl; context:{ links: link.children }"></ng-container>
            </ul>
        </li>
    </ng-template>
    

    接著會實作導覽連結的其餘轉譯。 請注意,變數 link 屬於型別 NavigationLink 以及該類別建立的所有方法/屬性皆可使用。 [routerLink] 已使用,而非正常 href 屬性。 這可讓我們連結至應用程式中的特定路由,不需要重新整理整頁。

    導覽的遞回部分也透過建立另一個來實施 <ul> 若目前 link 具有非空白 children 陣列。

  9. 更新 navigation.component.spec.ts 新增支援 RouterTestingModule

    code language-diff
     ...
    + import { RouterTestingModule } from '@angular/router/testing';
     ...
     beforeEach(async(() => {
        TestBed.configureTestingModule({
    +   imports: [ RouterTestingModule ],
        declarations: [ NavigationComponent ]
        })
        .compileComponents();
     }));
     ...
    

    新增 RouterTestingModule 為必要,因為元件使用 [routerLink].

  10. 更新 navigation.component.scss 將一些基本樣式新增至 NavigationComponent

@import "~src/styles/variables";

$link-color: $black;
$link-hover-color: $white;
$link-background: $black;

:host-context {
    display: block;
    width: 100%;
}

.navigation__item {
    list-style: none;
}

.navigation__item-link {
    color: $link-color;
    font-size: $font-size-large;
    text-transform: uppercase;
    padding: $gutter-padding;
    display: flex;
    border-bottom: 1px solid $gray;

    &:hover {
        background: $link-background;
        color: $link-hover-color;
    }

}

更新標題元件

現在 NavigationComponent 已實施, HeaderComponent 必須更新以參考它。

  1. 開啟終端機並導覽至 ui.frontend SPA檔案夾。 開始 webpack開發伺服器

    code language-shell
    $ npm start
    
  2. 開啟瀏覽器標籤並導覽至 http://localhost:4200/.

    webpack開發伺服器 應設定為從AEM的本機執行個體代理JSON模型(ui.frontend/proxy.conf.json)。 這可讓我們直接針對教學課程中先前在AEM中建立的內容進行編碼。

    功能表切換正在運作

    HeaderComponent 目前已經實作功能表切換功能。 接著,新增導覽元件。

  3. 返回您選擇的IDE並開啟檔案 header.component.tsui.frontend/src/app/components/header/header.component.ts.

  4. 更新 setHomePage() 移除硬式編碼字串並使用由AEM元件傳入的動態屬性的方法:

    code language-js
    /* header.component.ts */
    import { NavigationLink } from '../navigation/navigation-link';
    ...
     setHomePage() {
        if (this.hasNavigation) {
            const rootNavigationLink: NavigationLink = new NavigationLink(this.items[0]);
            this.isHome = rootNavigationLink.path === this.route.snapshot.data.path;
            this.homePageUrl = rootNavigationLink.url;
        }
    }
    ...
    

    的新執行個體 NavigationLink 建立依據 items[0],是從AEM傳入的導覽JSON模型的根目錄。 this.route.snapshot.data.path 傳回目前Angular路由的路徑。 此值用於決定目前的路由是否為 首頁. this.homePageUrl 用於填入 標誌.

  5. 開啟 header.component.html 和將導覽的靜態預留位置取代為新建立的參照 NavigationComponent

    code language-diff
        <div class="header-navigation">
            <div class="navigation">
    -            Navigation Placeholder
    +           <app-navigation [items]="items"></app-navigation>
            </div>
        </div>
    

    [items]=items 屬性傳遞 @Input() itemsHeaderComponentNavigationComponent 建置導覽的位置。

  6. 開啟 header.component.spec.ts 並為新增宣告 NavigationComponent

    code language-diff
        /* header.component.spect.ts */
    +   import { NavigationComponent } from '../navigation/navigation.component';
    
        describe('HeaderComponent', () => {
        let component: HeaderComponent;
        let fixture: ComponentFixture<HeaderComponent>;
    
        beforeEach(async(() => {
            TestBed.configureTestingModule({
            imports: [ RouterTestingModule ],
    +       declarations: [ HeaderComponent, NavigationComponent ]
            })
            .compileComponents();
        }));
    

    由於 NavigationComponent 現已用作 HeaderComponent 它需要宣告為測試平台的一部分。

  7. 儲存任何開啟檔案的變更並返回 webpack開發伺服器http://localhost:4200/

    完成的標頭導覽

    按一下功能表切換即可開啟導覽,且您應會看到已填入的導覽連結。 您應該能夠導覽至SPA的不同檢視。

瞭解SPA路由

現在導覽已實施,請在AEM中檢查路由。

  1. 在IDE中開啟檔案 app-routing.module.tsui.frontend/src/app.

    code language-js
    /* app-routing.module.ts */
    import { AemPageDataResolver, AemPageRouteReuseStrategy } from '@adobe/cq-angular-editable-components';
    import { NgModule } from '@angular/core';
    import { RouteReuseStrategy, RouterModule, Routes, UrlMatchResult, UrlSegment } from '@angular/router';
    import { PageComponent } from './components/page/page.component';
    
    export function AemPageMatcher(url: UrlSegment[]): UrlMatchResult {
        if (url.length) {
            return {
                consumed: url,
                posParams: {
                    path: url[url.length - 1]
                }
            };
        }
    }
    
    const routes: Routes = [
        {
            matcher: AemPageMatcher,
            component: PageComponent,
            resolve: {
                path: AemPageDataResolver
            }
        }
    ];
    @NgModule({
        imports: [RouterModule.forRoot(routes)],
        exports: [RouterModule],
        providers: [
            AemPageDataResolver,
            {
            provide: RouteReuseStrategy,
            useClass: AemPageRouteReuseStrategy
            }
        ]
    })
    export class AppRoutingModule {}
    

    routes: Routes = []; array會定義Angular元件對應的路徑或導覽路徑。

    AemPageMatcher 是自訂Angular路由器 UrlMatcher,會比對AEM中「看起來」屬於此Angular應用程式一部分的頁面的任何內容。

    PageComponent 是Angular元件,代表AEM中的頁面,用來呈現相符的路由。 此 PageComponent 將在教學課程稍後複習。

    AemPageDataResolver由AEM SPA編輯器JS SDK提供,為自訂 angular路由器解析程式 用來將路由URL (AEM中的路徑,包含.html副檔名)轉換為AEM中的資源路徑(頁面路徑減去副檔名)。

    例如, AemPageDataResolver 轉換路由的URL content/wknd-spa-angular/us/en/home.html 到以下路徑: /content/wknd-spa-angular/us/en/home. 用於根據JSON模型API中的路徑解析頁面內容。

    AemPageRouteReuseStrategy由AEM SPA編輯器JS SDK提供,為自訂 RouteReuseStrategy 防止重複使用 PageComponent 跨越路由。 否則,頁面「A」中的內容可能會在導覽至頁面「B」時顯示。

  2. 開啟檔案 page.component.tsui.frontend/src/app/components/page/.

    code language-js
    ...
    export class PageComponent {
        items;
        itemsOrder;
        path;
    
        constructor(
            private route: ActivatedRoute,
            private modelManagerService: ModelManagerService
        ) {
            this.modelManagerService
            .getData({ path: this.route.snapshot.data.path })
            .then(data => {
                this.path = data[Constants.PATH_PROP];
                this.items = data[Constants.ITEMS_PROP];
                this.itemsOrder = data[Constants.ITEMS_ORDER_PROP];
            });
        }
    }
    

    PageComponent 處理從AEM擷取的JSON時需要,並作為呈現路由的Angular元件使用。

    ActivatedRoute由Angular路由器模組提供,包含指出哪個AEM頁面的JSON內容應載入此Angular頁面元件例項中的狀態。

    ModelManagerService,會根據路由取得JSON資料,並將資料對應至類別變數 pathitemsitemsOrder. 這些資料隨後將傳遞至 AEMPageComponent

  3. 開啟檔案 page.component.htmlui.frontend/src/app/components/page/

    code language-html
    <aem-page
        class="structure-page"
        [attr.data-cq-page-path]="path"
        [cqPath]="path"
        [cqItems]="items"
        [cqItemsOrder]="itemsOrder">
    </aem-page>
    

    aem-page 包含 AEMPageComponent. 變數 pathitems、和 itemsOrder 傳遞至 AEMPageComponent. 此 AemPageComponent,透過SPA編輯器JavaScript SDK提供,接著會反複處理此資料,並根據JSON資料動態例項化Angular元件,如以下所示: 對應元件教學課程.

    PageComponent 其實只是 AEMPageComponent 而且它是 AEMPageComponent 如此一來,大部分繁重的工作都會正確地將JSON模型對應至Angular元件。

Inspect AEM中的SPA路由

  1. 開啟終端機並停止 webpack開發伺服器 若已啟動。 導覽至專案的根目錄,並使用您的Maven技能將專案部署到AEM:

    code language-shell
    $ cd aem-guides-wknd-spa
    $ mvn clean install -PautoInstallSinglePackage
    
    note caution
    CAUTION
    angular專案已啟用一些非常嚴格的Linting規則。 如果Maven組建失敗,請檢查錯誤並尋找 在列出的檔案中找到Lint錯誤。。修正篩選器發現的任何問題,並重新執行Maven命令。
  2. 導覽至AEM中的SPA首頁: http://localhost:4502/content/wknd-spa-angular/us/en/home.html 並開啟瀏覽器的開發人員工具。 熒幕擷取畫面如下,擷取自Google Chrome瀏覽器。

    重新整理頁面,您應該會看到XHR要求 /content/wknd-spa-angular/us/en.model.json,即SPA根目錄。 請注意,根據教學課程中先前進行的階層深度設定,SPA根範本僅包含三個子頁面。 這不包括 第3頁.

    初始JSON請求 — SPA根目錄

  3. 在開發人員工具開啟的狀態下,導覽至 第3頁

    第3頁導覽

    請注意,已提出新的XHR要求給: /content/wknd-spa-angular/us/en/home/page-2/page-3.model.json

    第3頁XHR要求

    AEM模型管理員瞭解 第3頁 JSON內容無法使用,並自動觸發其他XHR請求。

  4. 繼續使用各種導覽連結來導覽SPA。 請注意,不會提出其他XHR要求,也不會發生完整頁面重新整理。 這可讓一般使用者快速使用SPA,並減少傳回AEM的不必要請求。

    已實作導覽

  5. 透過直接導覽至以下位置,嘗試使用深層連結: http://localhost:4502/content/wknd-spa-angular/us/en/home/page-2.html. 請注意,瀏覽器的返回按鈕仍會繼續運作。

恭喜! congratulations

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

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

後續步驟 next-steps

建立自訂元件 — 瞭解如何建立要與AEM SPA編輯器搭配使用的自訂元件。 瞭解如何開發作者對話方塊和Sling模型,以擴充JSON模型來填入自訂元件。

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