ナビゲーションとルーティングの追加 navigation-routing
AEM ページと SPA エディター SDK を使用して SPA の複数のビューがサポートされている仕組みについて説明します。Angular ルートを使用して動的ナビゲーションを実装し、既存のヘッダーコンポーネントに追加します。
目的
- SPA エディターを使用する際に利用可能な SPA モデルのルーティングオプションについて説明します。
- Angular ルーティングを使用して SPA の様々なビュー間を移動する方法を説明します。
- AEM ページ階層に基づく動的ナビゲーションを実装します。
作成する内容
この章では、既存の Header
コンポーネントにナビゲーションメニューを追加します。 ナビゲーションメニューは AEM のページ階層に基づいて動作し、ナビゲーションコアコンポーネントから提供される JSON モデルを使用します。
前提条件
ローカル開発環境の設定に必要なツールと手順を確認します。
コードの取得
-
このチュートリアルの出発点となるものを 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
-
Maven を使用してコードベースをローカルの AEM インスタンスにデプロイします。
code language-shell $ mvn clean install -PautoInstallSinglePackage
AEM 6.x を使用する場合は、以下の
classic
プロファイルを追加します。code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic
-
従来の WKND リファレンスサイトの完成したパッケージをインストールします。WKND リファレンスサイトで提供される画像は、WKND SPA で再利用されます。 このパッケージは、AEM のパッケージマネージャーを使用してインストールできます。
いつでも、完成したコードを GitHub で確認したり、ブランチ Angular/navigation-routing-solution
に切り替えてローカルにチェックアウトしたりできます。
HeaderComponent の更新の調査 inspect-header
ここまでの章では、app.component.html
を介して組み込まれる純粋な Angular コンポーネントとして HeaderComponent
コンポーネントが追加されました。 この章では、 HeaderComponent
コンポーネントがアプリから削除され、 テンプレートエディターを使用して追加されます。これにより、ユーザーは AEM 内から HeaderComponent
のナビゲーションメニューを設定できます。
-
任意の IDE で、この章の SPA スタータープロジェクトを開きます。
-
ui.frontend
モジュール下で、ファイルheader.component.ts
(ui.frontend/src/app/components/header/header.component.ts
)を調べます 。コンポーネントを AEM コンポーネント
wknd-spa-angular/components/header
にマッピングできるように、HeaderEditConfig
とMapTo
の追加など、いくつかの更新が行われています。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);
items
の@Input()
注釈に注意してください。items
には、AEM から渡されたナビゲーションオブジェクトの配列が含まれます。 -
ui.apps
モジュールで、AEMHeader
コンポーネントの次のコンポーネント定義を調べます。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
-
ブラウザーを開き、AEMにログインします(http://localhost:4502/)。開始コードベースは、既にデプロイされている必要があります。
-
SPA ページテンプレート(http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-page-template/structure.html)に移動します。
-
最も外側の ルートレイアウトコンテナ を選択し、その ポリシー アイコンをクリックします。オーサリングのためにロック解除された レイアウトコンテナ を選択 しない ように注意してください。
-
現在のポリシーをコピーし、SPA 構造 という名前の新しいポリシーを作成します。
許可されたコンポーネント/一般 の下で、レイアウトコンテナ コンポーネントを選択します。
許可されたコンポーネント/WKND SPA ANGULAR - STRUCTURE の下で、ヘッダー コンポーネントを選択します。
許可されたコンポーネント/WKND SPAANGULAR - コンテンツ の下で、画像 および テキスト コンポーネントを選択します。合計 4 つのコンポーネントを選択する必要があります。
「完了」をクリックして、変更を保存します。
-
ページを更新します。 ロック解除された レイアウトコンテナ の上に ヘッダー コンポーネントを追加します。
-
ヘッダー コンポーネントを選択して、その ポリシー アイコンをクリックして、ポリシーを編集します。
-
「WKND SPA ヘッダー」という ポリシータイトル を持つポリシーを新規作成します。
プロパティ で次のことを行います。
- 「ナビゲーションルート」を
/content/wknd-spa-angular/us/en
に設定します。 - 「ルートレベルを除外」を 1 に設定します。
- 「すべての子ページを収集」のチェックを外します。
- 「ナビゲーション構造の深さ」を 3 に設定します。
これにより、
/content/wknd-spa-angular/us/en
の 2 レベル下のナビゲーションが収集されます。 - 「ナビゲーションルート」を
-
変更を保存すると、テンプレートの一部として、入力された
Header
が表示されます。
子ページの作成
次に、AEM で別のビューとして機能する追加のページを作成します。 また、AEM が提供する JSON モデルの階層構造も調べます。
-
Sites コンソール(http://localhost:4502/sites.html/content/wknd-spa-angular/us/en/home)に移動します。WKND SPA Angular ホームページ を選択し、作成/ページ をクリックします。
-
テンプレート の下で SPA ページ を選択します。プロパティ で、タイトル に「ページ 1」 と入力し、名前に「page-1」と入力します。
「作成」をクリックし、ダイアログのポップアップで「開く」をクリックして、AEM SPA エディターでページを開きます。
-
新しい テキスト コンポーネントをメインの レイアウトコンテナ に追加します。コンポーネントを編集し、RTE と H1 要素を使用して「ページ 1」というテキストを入力します(段落要素を変更するには、フルスクリーンモードにする必要があります)。
画像などのコンテンツを自由に追加できます。
-
AEM Sites コンソールに戻り、上記の手順を繰り返して、Page 1 の兄弟として「Page 2」という名前の 2 つ目のページを作成します。コンテンツを Page 2 に追加して、容易に識別できるようします。
-
最後に 3 つ目のページ「Page 3」を Page 2 の 子 として作成します。完了すると、サイト階層は次のようになります。
-
新しいタブで、AEM が提供する JSON モデル API(http://localhost:4502/content/wknd-spa-angular/us/en.model.json)を開きます。 この JSON コンテンツは、SPAが最初に読み込まれる際にリクエストされます。 外側の構造は次のようになります。
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 の後続のビューは迅速に読み込まれます。最初のページの読み込みが遅くなるため、最初の JSON リクエストでSPAのコンテンツを すべて 読み込むのは賢明ではありません。次に、ページの階層深度が収集される方法を見ていきましょう。
-
SPA Root テンプレート( http://localhost:4502/editor.html/conf/wknd-spa-angular/settings/wcm/templates/spa-app-template/structure.html)に移動します。
ページプロパティメニュー/ページポリシー をクリックします。
-
SPA Root テンプレートにある「階層構造」タブでは、収集される JSON コンテンツを制御できます。 構造深度 では、root の下にある子ページのサイト階層内での収集深度が決定されます。また、「構造パターン」フィールドを使用して、正規表現に基づいて追加のページを除外します。
構造深度 を 「2」 に変更します。
「完了」をクリックしてポリシーの変更を保存します。
-
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": {} } }
Page 3 のパス
/content/wknd-spa-angular/us/en/home/page-2/page-3
が最初の JSON モデルから削除されています。後で、AEM SPA Editor SDK が追加のコンテンツを動的に読み込む方法を確認します。
ナビゲーションの実装
次に、新しい NavigationComponent
でナビゲーションメニューを実装します。コードを header.component.html
で直接追加できますが、大きなコンポーネントを避ける方が良い方法です。 代わりに、 後で再利用できる可能性がある NavigationComponent
を実装します。
-
次の場所の AEM
Header
コンポーネントによって公開された JSON をレビューします。http://localhost:4502/content/wknd-spa-angular/us/en.model.jsoncode 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
の注釈にマッピングされます。 -
新しいターミナルウィンドウを開き、SPAプロジェクトの
ui.frontend
フォルダーに移動します。Angular CLI ツールを使用して新しいNavigationComponent
を作成します。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)
-
次に、新しく作成した
components/navigation
ディレクトリで Angular CLI を使用して、NavigationLink
という名前のクラスを作成します。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)
-
任意の IDE に戻り、
navigation-link.ts
こちら/src/app/components/navigation/navigation-link.ts
にあるファイルを開きます。 -
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 オブジェクトにすることが想定されます。ナビゲーション構造を容易に入力できるようにするために、このクラスはNavigationComponent
とHeaderComponent
の両方で使用します。データ変換は実行されません。このクラスは主に JSON モデルを強く入力するために作成されます。
this.children
はNavigationLink[]
のように入力され、コンストラクターよって再帰的にchildren
配列の各項目に、新しいNavigationLink
オブジェクトが作成されます。先に説明したように、Header
の JSON モデルは階層になっています。 -
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
のコンストラクターをテストするには十分です。 -
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
では、AEM の JSON モデルであるitems
という名前のobject[]
が想定されます。このクラスは、NavigationLink
オブジェクトの配列を返す単一のメソッドget navigationLinks()
を公開します。 -
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>
が生成され、navigation.component.ts
からget navigationLinks()
メソッドが呼び出されます。<ng-container>
は、recursiveListTmpl
という名前のテンプレートを呼び出すために使用され、links
という名前の変数として、navigationLinks
を渡します。次に
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
属性の代わりに使用されます。これにより、ページ全体を更新することなく、アプリ内の特定のルートにリンクできます。ナビゲーションの再帰部分は、現在の
link
に空でないchildren
配列がある場合、別の<ul>
を作成することによっても実装されます。 -
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]
を使用しているため必須です。 -
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
を更新する必要があります。
-
ターミナルを開き、SPA プロジェクト内の
ui.frontend
フォルダーに移動します。webpack 開発サーバー を開始します。code language-shell $ npm start
-
ブラウザータブを開き、http://localhost:4200/ に移動します。
webpack 開発サーバー は、AEM のローカル インスタンス(
ui.frontend/proxy.conf.json
)から JSON モデルをプロキシするように設定する必要があります。これにより、チュートリアルの前の段階に AEM 内で作成されたコンテンツに対して、直接コーディングすることができます。HeaderComponent
は現在、メニュー切り替え機能を実装しています。 次に、ナビゲーションコンポーネントを追加します。 -
選択した IDE に戻り、ファイル
header.component.ts
をui.frontend/src/app/components/header/header.component.ts
で開きます。 -
setHomePage()
メソッドをアップデートして、ハードコーディングされた文字列を削除し、AEM コンポーネントによって渡された動的な prop を使用します。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; } } ...
AEM から渡されたナビゲーション JSON モデルのルートである
items[0]
に基づいて、NavigationLink
の新しいインスタンスが作成されます。this.route.snapshot.data.path
は、現在の Angular ルートのパスを返します。この値は、現在のルートが ホームページ であるかどうかを判断するために使用されます。this.homePageUrl
を使用して、ロゴ 上のアンカーリンクを入力します。 -
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() items
を、HeaderComponent
からNavigationComponent
に渡し、そこでナビゲーションを構築します。 -
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
の一部として使用されるようになったため、テストベッドの一部として宣言する必要があります。 -
開いているファイルへの変更を保存し、webpack 開発サーバー: http://localhost:4200/ に戻ります
メニューの切替スイッチをクリックしてナビゲーションを開くと、入力されたナビゲーションリンクが表示されます。 SPA の様々なビューに移動できるはずです。
SPA ルーティングについて
ナビゲーションが実装されたので、AEM のルーティングを検査します。
-
IDE で、
ui.frontend/src/app
に置かれたファイルapp-routing.module.ts
を開きます。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 = [];
配列は、Angular コンポーネントマッピングへのルートまたはナビゲーションパスを定義します。AemPageMatcher
はカスタム Angular ルーター UrlMatcher であり、この Angular アプリケーションの一部である AEM にあるページに「似ている」ものすべてに一致します。PageComponent
は AEM にあるページを表す Angular コンポーネントであり、一致したルートをレンダリングするために使用されます。このPageComponent
は、チュートリアルの後半でレビューします。AEM SPA Editor JS SDK が提供する
AemPageDataResolver
は、拡張子 .html を含む AEM のパスであるルート URL を、拡張子を除いたページパスである AEM のリソースパスに変換するためのカスタム Angular Router Resolver です。例えば
AemPageDataResolver
は、content/wknd-spa-angular/us/en/home.html
のルートの URL を/content/wknd-spa-angular/us/en/home
のパスに変換します。これは、JSON モデル API のパスに基づいてページのコンテンツを解決するために使用されます。AEM SPA Editor JS SDK が提供する
AemPageRouteReuseStrategy
は、ルート間でのPageComponent
の再利用を防ぐカスタム RouteReuseStrategy です。再利用を防がないと、ページ「B」に移動すると、ページ「A」のコンテンツが表示される場合があります。 -
ui.frontend/src/app/components/page/
のpage.component.ts
ファイルを開きます。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 コンポーネントとして使用されます。Angular Router モジュールが提供する
ActivatedRoute
には、この Angular ページコンポーネントインスタンスに読み込む必要がある AEM ページの JSON コンテンツを示す状態が含まれています。ModelManagerService
は、ルートに基づいて JSON データを取得し、データをクラス変数path
、items
、itemsOrder
にマッピングします。これらは、その後、AEMPageComponent に渡されます -
ui.frontend/src/app/components/page/
でファイルpage.component.html
を開きます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 を含みます。変数path
、items
、itemsOrder
がAEMPageComponent
に渡されます。AemPageComponent
は SPA Editor JavaScript SDK を介して提供され、次にこのデータを繰り返し処理し、コンポーネントのマッピングチュートリアル見られるように、JSON データに基づいて Angular コンポーネントを動的にインスタンス化します。PageComponent
は、実際にはAEMPageComponent
のプロキシにすぎません。JSON モデルを Angular コンポーネントに正しくマッピングする重要な作業の大部分を実行するのはAEMPageComponent
です。
AEM で SPA ルーティングを調べる
-
ターミナルを開いて、webpack 開発サーバー を停止します(開始している場合) 。プロジェクトのルートに移動し、Maven のスキルを使用して AEMにプロジェクトをデプロイします。
code language-shell $ cd aem-guides-wknd-spa $ mvn clean install -PautoInstallSinglePackage
note caution CAUTION Angular プロジェクトで、非常に厳密な lint ルールが有効になっています。Maven ビルドに失敗した場合は、エラーを確認し、リストされたファイルで lint エラーを探します。lint で見つかった問題を修正し、Maven コマンドを再実行します。 -
AEM の SPA ホームページ(http://localhost:4502/content/wknd-spa-angular/us/en/home.html)に移動し、ブラウザーのデベロッパーツールを開きます。以下のスクリーンショットは、Google Chrome ブラウザーからキャプチャしたものです。
ページを更新すると、
/content/wknd-spa-angular/us/en.model.json
への XHR リクエストが表示されます。これは SPAのルートです。このチュートリアルで前述した SPA ルートテンプレートの階層の深さ設定に基づいて、3 つの子ページのみが含まれます。 これには、Page 3 は含まれません。 -
デベロッパーツールを開き、Page 3 に移動します。
/content/wknd-spa-angular/us/en/home/page-2/page-3.model.json
に対する新しい XHR リクエストが行われることを確認します。AEM Model Manager は、Page 3 JSON コンテンツは使用できず、追加の XHR リクエストを自動的にトリガーします。
-
様々なナビゲーションリンクを使用して SPA 内を移動し続けます。 追加の XHR リクエストが行われず、完全なページ更新が行われないことを確認します。これにより、エンドユーザーにとって SPA の処理が高速になり、AEM に返される不要なリクエストが減ります。
-
http://localhost:4502/content/wknd-spa-angular/us/en/home/page-2.html に直接移動して、ディープリンクを試してみます。ブラウザーの「戻る」ボタンが引き続き機能することを確認します。
おめでとうございます。 congratulations
これで、SPA Editor SDK で AEM ページにマッピングすることで、SPA の複数のビューをサポートする方法を学びました。 動的ナビゲーションは Angular ルーティングを使用して実装され、Header
コンポーネントに追加されています。
完成したコードを GitHub で確認する、または、ブランチ Angular/navigation-routing-solution
に切り替えて、コードをローカルでチェックアウトします。
次の手順 next-steps
カスタムコンポーネントの作成 - AEM SPA エディターで使用するカスタムコンポーネントを作成する方法を説明します。 オーサーダイアログと Sling モデルを開発して JSON モデルを拡張し、カスタムコンポーネントを設定する方法について説明します。