web-dev-qa-db-ja.com

Angular2ルーター:子モジュールに独自のルーティングルールを正しく読み込む方法

ここに私のAngular2アプリの構造があります:

enter image description here

これが私のコードの一部です。以下は、Angular2アプリのメインmoduleで、ルーティングルールと子モジュール(EdgeModule)をインポートし、一部のページに関連するコンポーネントを使用します。

app.module.ts

@NgModule({
    declarations: [
        AppComponent,
        PageNotFoundComponent,
        LoginComponent
    ],
    imports: [
        ...
        appRouting,
        EdgeModule
    ],
    providers: [
        appRoutingProviders,
        LoginService
    ],
    bootstrap: [AppComponent]
})

export class AppModule {
}

メインモジュールのルーティングルールは次のとおりです。ログインページと見つからないページへのパスがあります。

app.routing.ts

const appRoutes: Routes = [
    { path: 'login', component: LoginComponent },
    { path: '**', component: PageNotFoundComponent }
];

export const appRoutingProviders: any[] = [];

export const appRouting = RouterModule.forRoot(appRoutes, { useHash: true });

使用するコンポーネントを宣言し、独自のルーティングルールと2つの子モジュール(EdgeModuleおよびFirstSectionModule)をインポートするSecondSectionModuleは次のとおりです。

Edge.module.ts

@NgModule({
    declarations: [
        EdgeComponent,
        SidebarComponent,
        TopbarComponent
    ],
    imports: [
        ...
        edgeRouting,
        FirstSectionModule,
        SecondSectionModule
    ],
    providers: [
        AuthGuard
    ]
})

export class EdgeModule {
}

ご覧のとおり、トップバーとサイドバーのコンポーネントをロードするモジュールのルーティングルールは次のとおりです。

Edge.routing.ts

Paths['edgePaths'] = {
    firstSection: 'firstSection',
    secondSection: 'secondSection'
};

const appRoutes: Routes = [
    { path: '', component: EdgeComponent,
        canActivate: [AuthGuard],
        children: [
            { path: Paths.edgePaths.firstSection, loadChildren: '../somepath/first-section.module#FirstModule' },
            { path: Paths.edgePaths.secondSection, loadChildren: '../someotherpath/second-section.module#SecondModule' },
            { path: '', redirectTo: edgePaths.dashboard, pathMatch: 'full' }
        ]
    }
];

export const edgeRouting = RouterModule.forChild(appRoutes);

最後に、これは2つの子モジュールの1つであり、コンポーネントを持ち、ルーティングルールをインポートします。

first-section.module.ts

@NgModule({
    declarations: [
        FirstSectionComponent,
        SomeComponent
    ],
    imports: [
        ...
        firstSectionRouting
    ],
    providers: [
        AuthGuard,
    ]
})

export class FirstSectionModule {
}

これらは、FirstSectionModuleのページ(コンポーネント)のルーティングルールです。

first-section.routing.ts

Paths['firstSectionPaths'] = {
    someSubPage: 'some-sub-page',
    someOtherSubPage: 'some-other-sub-page'
};

const appRoutes: Routes = [
    {
        path: '',
        children: [
            { path: Paths.firstSectionPaths.someSubPage, component: someSubPageComponent},
            { path: Paths.firstSectionPaths.someOtherSubPage, component: someOtherSubPageComponent},
            { path: '', component: AnagraficheComponent }
        ]
    }
];

export const firstSectionRouting = RouterModule.forChild(appRoutes);

second-section.module.tsおよびsecond-section.routing.tsファイルについてもほぼ同じことが起こります。

アプリを実行すると、最初に読み込まれるのはFirstSectionComponentに関連するページで、サイドバーもトップバーもありません。

私のコードの何が問題なのか教えてもらえますか?コンソールにエラーはありません。

33
smartmouse

loadChildrenを使用してこれを試すことができます。homeModuleproductModuleaboutModuleには独自のルートルールがあります。

const routes: Routes = [
    { path: 'home', loadChildren: 'app/areas/home/home.module#homeModule' },
    { path: 'product', loadChildren: 'app/areas/product/product.module#ProductModule' },
    { path: 'drawing', loadChildren: 'app/areas/about/about.module#AboutModule' }
];

export const appRouting = RouterModule.forRoot(routes);

そして、ホームルートのルールは次のようになります

export const RouteConfig: Routes = [
    {
        path: '',
        component: HomeComponent,
        canActivate: [AuthGuard],
        children: [
            { path: '', component: HomePage },
            { path: 'test/:id', component: Testinfo},
            { path: 'test2/:id', component: Testinfo1},
            { path: 'test3/:id', component: Testinfo2}
        ]
    }
];

これは、モジュールの遅延読み込みとしても知られています。

{ path: 'lazy', loadChildren: 'lazy/lazy.module#LazyModule' }

ここで注意すべき重要な点がいくつかあります:コンポーネントの代わりにプロパティloadChildrenを使用します。モジュールを熱心にロードしないように、シンボルではなく文字列を渡します。モジュールへのパスだけでなく、クラスの名前も定義します。 LazyModuleには、独自のルーティングとLazyComponentというコンポーネントがあること以外に特別なことはありません。

これに関連するこの素晴らしいチュートリアルをご覧ください: https://angular-2-training-book.rangle.io/handout/modules/lazy-loading-module.html

App.routing.tsには、2つのルートのみがあり、メインセクションに移動するためのルートは含まれていません(図のように)。 mainセクションのモジュールをロードするために、loadchildrenプロパティを持つルートエントリが必要です。

routes: Routes = [...
{ 
path: 'main', loadChildren: '<file path>/<Edge module file name>#EdgeModule' 
}
...];

これにより、残りのモジュール、コンポーネントルート、およびEdgeModule内のすべてがロードされます。

1
CharithW

問題を正しく取得できるかどうかはわかりませんが、ルートを動的に生成するために使用した小さなコードスニペットを次に示します。

app.component.ts:

constructor(private _router: Router) {
}

ngOnInit() {
     ...
     this._router.config[0].children = myService.getRoutes(); 
     this._router.resetConfig(this._router.config);
     console.debug('Routes:', this._router.config);
     ...
}

OOTBソリューションではありませんが、現在のルートに関する情報を取得できます。

0
Sargon

これは依存性注入の問題です。 edgeModuleにFirstSectionModuleとSecondSectionModuleを挿入する必要はありません。FirstSectionModuleとSecondSectionModuleの内部で使用できるルートについては必要ありません。したがって、edgeModuleから削除するだけで機能します。

0
Vivek Kumar