JSS Angular アプリでのプレースホルダーの操作
このページの翻訳はAIによって自動的に行われました。可能な限り正確な翻訳を心掛けていますが、原文と異なる表現や解釈が含まれる場合があります。正確で公式な情報については、必ず英語の原文をご参照ください。
プレースホルダーは、Sitecore JSS で構築されたすべてのアプリケーションに欠かせないコンポーネントです。このトピックでは、Sitecore JSS Angular サンプル アプリケーションを使用して、その例を示します。
JSS Angular サンプル アプリケーションには、ルート プレースホルダーが付属しています。ルート プレースホルダーは src/app/routing/layout/layout.component.html
で定義されています。
sc-placeholder
コンポーネントが Angular 用 Sitecore JSS (@sitecorelabs/sitecore-jss-angular
) からインポートされます。
<sc-placeholder name="jss-main" [rendering]="route" (loaded)="onPlaceholderLoaded($event)"></sc-placeholder><sc-placeholder name="jss-main" [rendering]="route"></sc-placeholder>
sc-placeholder
Angular コンポーネントは、jss-main
という値の name
属性を保持しています。この属性は jss-main
という名前の Sitecore プレースホルダーを表しています。プレースホルダーは、プレースホルダー コンポーネントの [rendering]
入力にバインドされたデータで示されるように、ルート データに基づいて 1 つ以上のコンポーネントをレンダリングします。
<sc-placeholder name="jss-main" [rendering]="route" (loaded)="onPlaceholderLoaded($event)"></sc-placeholder>
sc-placeholder
を、既存の DOM 要素に属性として適用できます。
ルート データの発生元の理解
プレースホルダー コンポーネントが route
データを受け取る方法を理解するには、さまざまなコンポーネント、アプリケーション モジュール、サービスがどのように相互連携するかを理解する必要があります。
本番環境では、ユニバーサル レンダリングをサポートするために、JSS Angular アプリケーションを構築するためのスクリプトによって、サーバー バンドルとクライアント バンドルが構築されます。スクリプト jss build
を実行すると、これらのバンドルは以下の場所に配置されます。
-
クライアント バンドル -
dist/browser/
。 -
サーバー バンドル -
dist/server.bundle.js
。
2 つのバンドルは単独では実行できません。これらのバンドルはサービスされる必要があり、そのためにはサーバーが必要になります。JSS には、サーバー バンドルを実行できる Node 用の JavaScript ビュー エンジンが付属しています。JSS JavaScript ビュー エンジンでは、renderView
関数をエクスポートするサーバー バンドルが必要になります。
2 つのバンドルを構築し、サービスするために、JSS Angular アプリでは、関連するアプリ モジュールとデータ サービスに基づいて、アプリケーション用の 2 つのエントリ ポイントを定義します。
ファイル src/main.server.ts
では、サーバー バンドルのエントリ ポイントが定義され、src/app/app.server.module.ts
で定義されているサーバー AppServerModule
用のアプリケーション モジュールがブートストラップされます。AppServerModule
は、src/app/jss-context.server-side.service.ts
で定義されている JssContextServerSideService
(サーバー上で実行され、JSS アプリのコンテキスト データを格納) を使用します。コンテキスト データには、現在のルートのデータと Sitecore コンテキスト データが含まれています。
ファイル src/main.ts
では、クライアント バンドルのエントリ ポイントが定義され、src/app/app.module.ts
で定義されているクライアント レンダリング AppModule
用のアプリケーション モジュールがブートストラップされます。AppModule
は、src/app/jss-context.service.ts
で定義されている JssContextService
(クライアント上でブラウザーを使って実行され、JSS アプリのコンテキスト データを格納) を使用します。
アプリケーションがブラウザで実行されると、サーバーはサーバー バンドルから、AppServerModule
をレンダリングする renderView
関数を呼び出し、JSS アプリ用のコンテキスト データを準備します。実装の詳細については、ファイル server.bundle.ts
および関連するサービスを参照してください。どちらのコンテキスト サービスも Angular のクラス TransferState
を使用しています。このクラスは、データを正規化した後でサーバー側のアプリケーション モジュールからクライアント側のアプリケーション モジュールに転送されるキー値ストアです。
renderModule(AppServerModule, {
document: template,
url: path,
extraProviders: [
// custom injection with the initial state that SSR should utilize
{ provide: 'JSS_SERVER_LAYOUT_DATA', useValue: transferState },
{ provide: 'JSS_SERVER_VIEWBAG', useValue: state.viewBag },
],
})
.then((html) => callback(null, { html }))
.catch((err) => callback(err, null));
クライアント側の AppModule
は、src/app/app.component.ts
で定義されたルート アプリケーション コンポーネント AppComponent
をブートストラップし、ファイル src/app/routing/routing.module.ts
で定義された RoutingModule
クラスをインポートします。RoutingModule
は、Angular ルーターをアプリケーション ルートにアタッチする処理を実行します。これにより、JSS Angular アプリでは Angular ルーター アウトレットを使用することが可能になります。
RoutingModule
は、ルーター アウトレット プレースホルダーでレンダリングするコンポーネントを定義します。このコンポーネントは、src/app/routing/layout/layout.component.ts
ファイルで定義されている LayoutComponent
です。RoutingModule
は、ルートを解決するときにアクティブなルートの状態を設定する JssRouteResolver
プロバイダーを使用します。
最後に、route
とレイアウト データの両方が挿入された LayoutComponent
では、アクティブなルートをサブスクライブし、Sitecore コンテキストからルート データを抽出することができます。
この時点で、プレースホルダー コンポーネントは、本番環境の設定においてルートの HTML マークアップをレンダリングすることができます。
切断モードで作業している場合、JSS アプリケーションはローカルに定義されたファイルからルート データを取得します。サンプル アプリケーションでは、事前定義されたローカル データがフォルダ src/data
に保存されています。ホーム ページなどのルートを読み込むとき、アプリケーションはファイル src/data/en.yml
からデータを取得します。応答には、ルートの JSON データが含まれています。
{
"context": {
"pageEditing": false,
"site": {
"name": "JssDisconnectedLayoutService"
},
"pageState": "normal",
"language": "en"
},
"route": {
"databaseName": "available-in-connected-mode",
"deviceId": "available-in-connected-mode",
"itemId": "home-page",
"itemLanguage": "en",
"itemVersion": 1,
"layoutId": "available-in-connected-mode",
"templateId": "available-in-connected-mode",
"templateName": "available-in-connected-mode",
"name": "home",
"fields": {
"pageTitle": {
"value": "Welcome to Sitecore JSS"
}
},
"placeholders": {
"jss-main": [
{
"uid": "{2C4A53CC-9DA8-5F51-9D79-6EE2FC671B2D}",
"componentName": "ContentBlock",
"dataSource": "available-in-connected-mode",
"params": {},
"fields": {
"heading": {
"value": "Welcome to Sitecore JSS"
},
"content": {
"value": "<p>Thanks for using JSS. Here are some resources to get you started:</p>"
}
}
}
]
}
}}
route
プロパティの JSON データ構造には、placeholders
のリストが含まれています。各プレースホルダーの名前は、コンポーネントの配列に関連付けられています。プレースホルダーへのコンポーネントのマッピングは、コンポーネント配置ルールと呼ばれます。
sc-placeholder
コンポーネントは route
プロパティ内の placeholders
オブジェクトにアクセスできるため、このコンポーネントでは、名前 (jss-main
) を使用して一致するプレースホルダーを検索し、プレースホルダー内のコンポーネントの配列をレンダリングします。この例では、一般的な Angular コンポーネントである ContentBlockComponent
コンポーネントを動的にレンダリングし、依存関係挿入トークンを介して heading
と content
というフィールドを提供します。
import { Component, Input } from '@angular/core';
import { ComponentRendering } from '@sitecore-jss/sitecore-jss-angular';
@Component({
selector: 'app-content-block',
templateUrl: './content-block.component.html',
})
export class ContentBlockComponent {
@Input() rendering: ComponentRendering;
}
rendering
プロパティには、データから取得される ContentBlockComponent
コンポーネントに関連するすべての情報が含まれています。
"componentName": "ContentBlock",
"dataSource": "available-in-connected-mode",
"params": {},
"fields": {
"heading": {
"value": "Welcome to Sitecore JSS"
},
"content": {
"value": "<p>Thanks for using JSS. Here are some resources to get you started:</p>"
}
}
プレースホルダーとコンポーネントのネスト
コンポーネントには独自の sc-placeholder
コンポーネントを含めることができるため、コンポーネントの配置ルールで placeholders
を使用して、このコンポーネントの内容を定義できます。
たとえば、WelcomeComponent
コンポーネントには、次が含まれる場合があります。
@Component({
selector: 'app-welcome',
template: `
<sc-placeholder name="welcome" [rendering]="rendering"></sc-placeholder>
`
})
export class WelcomeComponent {
rendering: any;
}
この場合、コンポーネント配置ルールで子コンポーネントを定義します。
{
componentName: 'Welcome',
fields: {
title: {
value: 'Sitecore Experience Platform + JSS',
},
text: {
value: '<p>...</p>',
},
logoImage: {
value: {
src: '/assets/img/sc_logo.png',
alt: 'Logo'
},
},
},
placeholders: {
welcome: [
{
componentName: 'AnotherComponent',
fields: {
/* etc */
}
}
]
}
}
入力バインディングと出力バインディング
sc-placeholder
で [inputs]
と [outputs]
のバインディング プロパティを使用して、カスタム プロパティをコンポーネントにバインドできます。これらのプロパティにより、プレースホルダー内にあるすべてのコンポーネントのプロパティに対する入出力バインディングが可能になります。
このため、子コンポーネントが sc-placeholder
によって動的に作成された場合でも、子コンポーネントとのオーケストレーション/インタラクション を行うことができます。これは、Sitecore XP でも管理/最適化を行う必要がある複雑なユーザー フローで特に役立ちます。
[inputs]
と [outputs]
の簡単な使用例を次に示します。
@Component({
selector: 'my-container-component',
template: `<sc-placeholder
name="placeholder"
[rendering]="rendering"
[inputs]="inputs"
[outputs]="outputs"
></sc-placeholder>`
})
class MyContainerComponent {
@Input() public rendering: any;
inputs = {
hello: 'world',
something: () => 'can be really complex'
};
outputs = {
onSomething: (type) => alert(type)
}
}
@Component({selector: 'my-rendering')
class MyRendering {
// standard on any placeholder-managed component
@Input() public rendering: any;
// additional properties for input/output binding
@Input() hello: string;
@Input() something: Function;
@Output() onSomething = new EventEmitter<string>();
}
プレースホルダーの遅延読み込み
Sitecore コンポーネントを遅延読み込みすると、既定ではプレースホルダーが空で表示されます。コンポーネントの読み込み中に表示されるコンポーネントの一時的な本体を指定できます。コンポーネントの読み込みが完了すると、一時的な本体が実際のコンテンツに置き換わります。簡単な例を次に示します。
<sc-placeholder [rendering]="rendering">
<img *scPlaceholderLoading src="loading.gif">
</sc-placeholder>
プレースホルダーの強化
Placeholder
コンポーネントは、開発者エクスペリエンスを向上させるいくつかのカスタマイズをサポートしています。
エラー コンポーネント
プレースホルダーでレンダリング エラーが発生した場合、プレースホルダーにはプレースホルダーのコンテンツではなくエラー コンポーネントが表示され、エラーの詳細がコンソールに記録されます。このコンポーネントをカスタマイズするには、errorComponent
プロップを使って、独自の React コンポーネントを代わりに使用します。
MissingComponent コンポーネント
componentFactory
で認識されないレンダリング名がプレースホルダーに含まれている場合 (たとえば、バックエンド開発者が Foo レンダリングを作成し、それをページに追加したが、foo.component.ts
がまだ存在していない場合)、レンダリングは、Angular コンポーネントの missingComponentComponent
プロパティで定義された MissingComponent
コンポーネントに置き換えられます。既定の実装はシンプルなメッセージですが、missingComponentComponent
プロパティで独自の Angular コンポーネントを使用して、この実装をカスタマイズできます。
非表示のレンダリングの処理
レンダリングがパーソナライゼーション ルールによって非表示になっている場合、レンダリングに JSS 実装が欠落している際のエラー メッセージを回避するために、レンダリングは HiddenRendering
コンポーネントに置き換えられます。hiddenRenderingComponent
プロパティを使用することで、独自のコンポーネントを作成し、プレースホルダーに提供できます。