ナビゲーションとルーティングの追加 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 -PautoInstallSinglePackageAEM 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
-
ブラウザーを開き、http://localhost:4502/のAEMにログインします。 開始コードベースは、既にデプロイされている必要があります。
-
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 ルート テンプレート(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 を実装します。
-
http://localhost:4502/content/wknd-spa-angular/us/en.model.jsonのAEM
Headerコンポーネントによって公開された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の注釈にマッピングされます。 -
新しいターミナルウィンドウを開き、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 -PautoInstallSinglePackagenote caution CAUTION Angular プロジェクトで、非常に厳密な lint ルールが有効になっています。 Mavenのビルドが失敗した場合は、エラーを確認し、リストされたファイルに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 モデルを拡張し、カスタムコンポーネントを設定する方法について説明します。