AngularのJSSを使用するためのヒント
このページの翻訳はAIによって自動的に行われました。可能な限り正確な翻訳を心掛けていますが、原文と異なる表現や解釈が含まれる場合があります。正確で公式な情報については、必ず英語の原文をご参照ください。
JSS Angularアプリの操作は、通常のAngularアプリケーションの操作と似ています。このトピックでは、JSS固有の推奨事項について説明します。
<base>タグは使用しないでください
ほとんどのAngularアプリケーションは、HTMLテンプレートで <base /> タグを使用して、ルーティングの基本hrefを設定します。JSS Angularアプリは、Sitecoreエクスペリエンス エディターの機能と互換性がないため、この手法を使用できません。別の方法として、APP_BASE_HREFトークンを使用して、依存関係の挿入を通じてルーティング ベース ディhrefを提供することもできます。サンプル アプリケーションでは、APP_BASE_REF手法を使用します。
使用頻度の低いJSSコンポーネントに遅延ロードされたコンポーネントを使用する
JSS Angularは、初期ページの読み込み時間を改善し、帯域幅を減らすために、遅延読み込みコンポーネントをサポートしています。これは、JSSを使用しないAngularの遅延ロードルートと似ており、コンポーネントがルートで使用されるときに動的にロードされたモジュールを取得します。一般に、ほとんどすべてのルートで使用されていないコンポーネントは、遅延ロードの候補として適しています。
遅延ロードされたコンポーネントをスキャフォールディングして自動登録するには、jss scaffold <componentName> --lazyloadを使用できます。
既存のコンポーネントを遅延読み込みするには、コンポーネントフォルダにAngularモジュールを追加する必要があります。たとえば、MyComponentコンポーネントの場合、次のようになります。
import { NgModule } from '@angular/core';
import { JssModule } from '@sitecore-jss/sitecore-jss-angular';
import { MyComponent } from './my.component';
@NgModule({
imports: [
JssModule.forChild(MyComponent)
],
declarations: [
MyComponent,
],
})
export class MyModule { }
既定のコード生成app-components.module.tsを使用する場合、コード ジェネレーターはコンポーネントを遅延読み込みとして自動的に登録します。それ以外の場合は、遅延ロードされたコンポーネントに対してJssModule.withComponents() の2番目のパラメーターを使用でき、遅延ロードされたルートと同じように機能します。例えば:
@NgModule({
imports: [
AppComponentsSharedModule,
JssModule.withComponents([
// non-lazy components
], [
// In this case, 'path' is the component name, and loadChildren is the module to load for it.
// This is exactly like lazy loaded routes. In fact, it uses the router under the hood to do it.
// loadChildren is the resolved module, with the path and then the export name.
{ path: 'My', loadChildren: import('./my/my.module').then(mod => mod.MyModule) }
]),
],
exports: [
JssModule,
AppComponentsSharedModule,
],
declarations: [
// non-lazy components
],
})
export class AppComponentsModule { }
また、1つのモジュールから複数のコンポーネントをロードすることもできます。これにより、アプリケーションのコード分割が改善され、コンポーネントをロード可能なグループにバンドルすることで、アプリケーション・リソースをロードする呼び出しが減ります。
複数コンポーネントの読み込みは、既定のコード生成と互換性がありません。この手法を使用するには、コード生成をオフにし、app-components.module.tsファイルを手動で管理する必要があります。
複数のコンポーネントを遅延読み込みするには、JssModule.forChild() メソッドを使用して2つ以上のコンポーネントを遅延読み込みモジュールに登録する必要があります。コンポーネント名とコンポーネント・タイプを指定する必要があります。例えば:
import { NgModule } from '@angular/core';
import { ROUTES } from '@angular/router';
import { JssModule, DYNAMIC_COMPONENT } from '@sitecore-jss/sitecore-jss-angular';
import { FirstComponent } from './first.component';
import { SecondComponent } from './second.component';
@NgModule({
imports: [
{
ngModule: JssModule,
providers: [
{
provide: DYNAMIC_COMPONENT,
useValue: {
'FirstComponent': FirstComponent,
'SecondComponent': SecondComponent
}
},
{
provide: ROUTES,
useValue: [],
multi: true
}
]
}
],
declarations: [
FirstComponent,
SecondComponent
],
})
export class MyModule { }
コンポーネントモジュールに変更はありません。複数のコンポーネントを遅延読み込みする場合、コンポーネントが同じモジュールからのものである場合は、loadChildrenに同じ値を設定する必要があります。また、パス値は、遅延読み込みモジュールの初期化からのコンポーネント名と同じである必要があります。
@NgModule({
imports: [
AppComponentsSharedModule,
JssModule.withComponents(
[
// non-lazy components
],
[
{
path: 'FirstComponent',
loadChildren: import('./my/my.module').then((mod) => mod.MyModule),
},
{
path: 'SecondComponent',
loadChildren: import('./my/my.module').then((mod) => mod.MyModule),
},
]
),
],
exports: [JssModule, AppComponentsSharedModule],
declarations: [
// non-lazy components
],
})
export class AppComponentsModule { }
コンポーネントは、canActivateオプションとresolveオプションもサポートできます。
-
canActivateコンポーネントをレンダリングするかどうかを決定するガードが含まれています。
-
resolveコンポーネントをレンダリングする前に、コンポーネントデータをロードします。
例えば:
@NgModule({
imports: [
AppComponentsSharedModule,
JssModule.withComponents(
[
// non-lazy components
],
[
{
path: 'FirstComponent',
loadChildren: import('./my/my.module').then((mod) => mod.MyModule),
canActivate: [CustomCanActivate, (input: GuardInput) => {
// The following conditional return statements require JSS 21.9+ or 22.5+ to work correctly.
// If you're using an earlier version of JSS, omit them from your code.
/* if (input.routerState.url === '/redirect-command') {
return new RedirectCommand(input.router.parseUrl('/target'));
}
if (input.routerState.url === '/tree-url') {
return input.router.parseUrl('/target');
} */
return of(true);
}],
},
{
path: 'SecondComponent',
loadChildren: import('./my/my.module').then((mod) => mod.MyModule),
canActivate: (input: GuardInput) => {
return of(true);
},
resolve: {
loadedData: {
resolve(_input: GuardInput) {
return { foo: 'bar' };
},
},
}
},
]
),
],
exports: [JssModule, AppComponentsSharedModule], declarations: [
// non-lazy components
],
})
export class AppComponentsModule { }
これらのオプションをクラスで使用するには、JssCanActivateやJssResolveインターフェイスを実装します。
コンポーネントがdisplay: blockでスタイル設定されていることを確認します
AngularでUIコンポーネントを書き込む場合、すべての新しいコンポーネントのデフォルトの表示スタイルはinlineです。エクスペリエンス エディタでコンポーネントが期待どおりに機能するようにするには、すべてのコンポーネント ルート要素の表示スタイルをdisplay: blockに設定する必要があります。例えば:
:host {
display: block;
}
この制限を回避する別の方法は、コンポーネントセレクタを変更して、<div /> などの既存のDOM要素を使用して必要な表示スタイルを取得することです。
Angularスタイルガイドでは、属性セレクターやクラスセレクターの代わりにカスタム要素を使用することを推奨しているため、CSSアプローチを使用することをお勧めします。
例えば:
@Component({
selector: 'div [app-hello-world]',
templateUrl: `
Hello world
`,
})
export class HelloWorldComponent {
rendering: any;
}
sc-placeholder属性を使用して、ラッピング要素を制御します
プレースホルダーコンテンツのラッパー要素を制御する場合は、<sc-placeholder>コンポーネントの代わりにsc-placeholder属性を使用できます。
<section sc-placeholder name="my-section" [rendering]="rendering"></section>
Angularスタイルガイドでは、一般的に属性やクラスセレクターの代わりにカスタム要素を使用することを推奨しているため、ユースケースを慎重に検討してください。
sc-placeholder属性を使用する代わりに、プレースホルダーコンポーネントを目的のHTML要素でラップすることもできます。例えば:
<section>
<sc-placeholder
name="my-section"
[rendering]="rendering"/>
</section>
ng-containerを構造ディレクティブと共に使用する
JSSは、フィールドヘルパーに構造ディレクティブを使用します。Angularでは1つの要素に対して複数の構造ディレクティブを許可しないため、ngIf、ngFor、ngSwitchCaseなどの他の構造ディレクティブを <ng-container />などのラッパーコンポーネントに適用することをお勧めします。例えば:
<ng-container *ngIf="condition">
<span *scText="myField"></span>
</ng-container>