AngularのJSSを使用するためのヒント

Version: 22.x
日本語翻訳に関する免責事項

このページの翻訳は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コンポーネントの場合、次のようになります。

RequestResponse
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番目のパラメーターを使用でき、遅延ロードされたルートと同じように機能します。例えば:

RequestResponse
@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つ以上のコンポーネントを遅延読み込みモジュールに登録する必要があります。コンポーネント名とコンポーネント・タイプを指定する必要があります。例えば:

RequestResponse
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に同じ値を設定する必要があります。また、パス値は、遅延読み込みモジュールの初期化からのコンポーネント名と同じである必要があります。

RequestResponse
@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コンポーネントをレンダリングする前に、コンポーネントデータをロードします。

例えば:

RequestResponse
@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 { }
先端

これらのオプションをクラスで使用するには、JssCanActivateJssResolveインターフェイスを実装します。

コンポーネントがdisplay: blockでスタイル設定されていることを確認します

AngularでUIコンポーネントを書き込む場合、すべての新しいコンポーネントのデフォルトの表示スタイルはinlineです。エクスペリエンス エディタでコンポーネントが期待どおりに機能するようにするには、すべてのコンポーネント ルート要素の表示スタイルをdisplay: blockに設定する必要があります。例えば:

RequestResponse
:host {
  display: block;
}

この制限を回避する別の方法は、コンポーネントセレクタを変更して、<div /> などの既存のDOM要素を使用して必要な表示スタイルを取得することです。

例えば:

RequestResponse
@Component({
  selector: 'div [app-hello-world]',
  templateUrl: `
    Hello world
  `,
})
export class HelloWorldComponent {
  rendering: any;
}

sc-placeholder属性を使用して、ラッピング要素を制御します

プレースホルダーコンテンツのラッパー要素を制御する場合は、<sc-placeholder>コンポーネントの代わりにsc-placeholder属性を使用できます。

RequestResponse
<section sc-placeholder name="my-section" [rendering]="rendering"></section>

Angularスタイルガイドでは、一般的に属性やクラスセレクターの代わりにカスタム要素を使用することを推奨しているため、ユースケースを慎重に検討してください。

sc-placeholder属性を使用する代わりに、プレースホルダーコンポーネントを目的のHTML要素でラップすることもできます。例えば:

RequestResponse
<section> 
  <sc-placeholder
    name="my-section"    
    [rendering]="rendering"/>
</section>

ng-containerを構造ディレクティブと共に使用する

JSSは、フィールドヘルパーに構造ディレクティブを使用します。Angularでは1つの要素に対して複数の構造ディレクティブを許可しないため、ngIfngForngSwitchCaseなどの他の構造ディレクティブを <ng-container />などのラッパーコンポーネントに適用することをお勧めします。例えば:

RequestResponse
<ng-container *ngIf="condition">
  <span *scText="myField"></span>
</ng-container>

何かフィードバックはありますか?

この記事を改善するための提案がある場合は、