ウェブサイト検索

TypeScript - Angular ルーター - 子ルート下の名前付き router-outlet


私はAngularアプリで複数のルーターアウトレットを使用しようとしています。シェルコンテナの中で複数のルーターアウトレットを使用しようとすると、問題が発生します。

意図された動作は、私がそれらのパスを訪れたときに、メインコンポーネントと詳細コンポーネントの両方がレンダリングされることです。

https://stackblitz.com/edit/angular-ivy-w9omb3?file=src%2Fapp%2Fapp.component.html

しかし、この例では、app-routing.module は子ルートを持たないフラットなルート構造を使用しています。

// app-routing.module.ts in flat solution
const routes: Routes = [
  { path: '', component: EmptyShellComponent },
  {
    path: 'feature1',
    loadChildren: () =>
      import('./feature-one/feature-one.module').then(
        (m) => m.FeatureOneModule
      ),
  },
  {
    path: 'feature2',
    loadChildren: () =>
      import('./feature-two/feature-two.module').then(
        (m) => m.FeatureTwoModule
      ),
  },
];

アプリの routing モジュールで自分のルートがどのように見えるか:

//app-routing.module.ts in solution with children routes
const routes: Routes = [
  {
    path: '',
    component: ShellComponent,
    children: [
      { path: '', component: EmptyShellComponent },
      {
        path: 'feature1',
        loadChildren: () =>
          import('./feature-one/feature-one.module').then(
            (m) => m.FeatureOneModule
          ),
      },
      {
        path: 'feature2',
        loadChildren: () =>
          import('./feature-two/feature-two.module').then(
            (m) => m.FeatureTwoModule
          ),
      },
    ],
  },
];

しかし、この構造を使用すると、詳細用の router-outlet が何もレンダリングできません: https://stackblitz.com/edit/angular-ivy-yasztr?file=src%2Fapp%2Fapp-routing.module.ts

この問題に取り組むために、シェルの子モジュールで複数のルーターアウトレットを許可するにはどのようなアプローチを取るべきでしょうか?

編集

要件として、シェルレベルで詳細ビューのための指定されたスペースを持ちたいと考えています。そこでは、異なるモジュールから異なる詳細コンポーネントを読み込むことができます。これは何らかの方法で可能でしょうか?私は、feature1のメインコンポーネントを閲覧している同時に、feature2の詳細も閲覧できるようにしたいです。また、両方のモジュールを遅延ロードしたいと考えています。

編集 2

app.component.html に名前付きの router-outlet を追加すると、次の状態になります:

異なるモジュールからの詳細はレンダリングされますが、シェルの外側にあります。

更新された stackblitz: https://stackblitz.com/edit/angular-ivy-ahptuq?file=src%2Fapp%2Fapp.component.html

回答 #1

Angularのルーティングは、最大で1つのプライマリルーターアウトレットと、0個以上の補助ルーターアウトレットを持つことができます。補助アウトレットを作成するには、ただ一意の名前を付ければよいです。

<router-outlet></router-outlet>
<router-outlet name="aux"></router-outlet>

プライマリのアウトレットは任意で、すべて名前を付けても構いません。私のテストでは、Angularは各ユニークな名前に対して1つのアウトレットだけをレンダリングするようです。

aux アウトレットにパスを割り当てるには、Route に outlet プロパティを追加するだけです

const routes: Routes = [
  {
    path: 'features',
    component: FeatureOneComponent,
  },
  {
    path: 'features',
    component: FeatureTwoComponent,
    outlet: 'aux',
  },
];

現在、両方のコンポーネントがfeaturesパスに表示されます。

もう一つの解決策は、両方のコンポーネントを囲むコンポーネントに入れて、単一の router-outlet を使ってそれにナビゲートすることです。

補助パスのナビゲートに関する詳細はこちら: https://www.techiediaries.com/angular-router-multiple-outlets/#Create_Named_Router_Outlet

もし別のルーティングされたコンポーネントの内側にルーターアウトレットを置きたい場合は、children配列を使用できます: https://blog.devgenius.io/the-art-of-nested-router-outlets-in-angular-dafb38245a30。ネストされたルーターアウトレットにユニークな名前を付ける必要はありません。

回答 #2

子ルートの場合、あなたが話しているのはネストされたルーターアウトレットであり、複数の router-outlet ディレクティブが1つのコンポーネントのHTMLの一部ではない場合です。その場合、アウトレットの名前付けは必要ありません。詳細は以下で読むことができます:-

https://blog.devgenius.io/the-art-of-nested-router-outlets-in-angular-dafb38245a30

関連記事