RouterModule.forRoot(ROUTES) と RouterModule.forChild(ROUTES) の比較 質問する

RouterModule.forRoot(ROUTES) と RouterModule.forChild(ROUTES) の比較 質問する

これら 2 つの違いは何ですか? また、それぞれの使用例は何ですか?

ドキュメントあまり役に立ちません:

forRoot は、すべてのディレクティブ、指定されたルート、およびルーター サービス自体を含むモジュールを作成します。

forChild は、すべてのディレクティブと指定されたルートを含むモジュールを作成しますが、ルーター サービスは含まれません。

私の漠然とした推測では、1 つは「メイン」モジュール用で、もう 1 つはインポートされたモジュール用です (メイン モジュールから既にサービスが利用可能であるため) が、使用例を実際に思いつくことはできません。

ベストアンサー1

この記事を読むことを強くお勧めします:

プロバイダー付きモジュール

モジュールをインポートするときは、通常、モジュール クラスへの参照を使用します。

@NgModule({
    providers: [AService]
})
export class A {}

-----------------------------------

@NgModule({
    imports: [A]
})
export class B

この方法では、モジュールに登録されたすべてのプロバイダーAがルート インジェクターに追加され、アプリケーション全体で使用できるようになります。

ただし、次のようにプロバイダーにモジュールを登録する別の方法もあります。

@NgModule({
    providers: [AService]
})
class A {}

export const moduleWithProviders = {
    ngModule: A,
    providers: [AService]
};

----------------------

@NgModule({
    imports: [moduleWithProviders]
})
export class B

これは前のものと同じ意味を持ちます。

遅延ロードされたモジュールには独自のインジェクターがあることはご存知でしょう。したがって、AServiceアプリケーション全体で利用できるように登録し、一部はBService遅延ロードされたモジュールでのみ利用できるようにしたいとします。次のようにモジュールをリファクタリングできます。

@NgModule({
    providers: [AService]
})
class A {}

export const moduleWithProvidersForRoot = {
    ngModule: A,
    providers: [AService]
};

export const moduleWithProvidersForChild = {
    ngModule: A,
    providers: [BService]
};

------------------------------------------

@NgModule({
    imports: [moduleWithProvidersForRoot]
})
export class B
    
// lazy loaded module    
@NgModule({
    imports: [moduleWithProvidersForChild]
})
export class C

今後は、BService遅延ロードされた子モジュールに対してのみ使用可能になり、AServiceアプリケーション全体で使用できるようになります。

上記を次のようにエクスポートされたモジュールとして書き直すことができます。

@NgModule({
    providers: [AService]
})
class A {
    forRoot() {
        return {
            ngModule: A,
            providers: [AService]
        }
    }

    forChild() {
        return {
            ngModule: A,
            providers: [BService]
        }
    }
}

--------------------------------------

@NgModule({
    imports: [A.forRoot()]
})
export class B

// lazy loaded module
@NgModule({
    imports: [A.forChild()]
})
export class C

###これは RouterModule とどのように関係するのでしょうか? 両方が同じトークンを使用してアクセスされると仮定します。

export const moduleWithProvidersForRoot = {
    ngModule: A,
    providers: [{provide: token, useClass: AService}]
};

export const moduleWithProvidersForChild = {
    ngModule: A,
    providers: [{provide: token, useClass: BService}]
};

token個別の構成を使用すると、遅延ロードされたモジュールから要求するときに、BService計画どおりの結果が得られます。

RouterModule はROUTESトークンを使用して、モジュール固有のすべてのルートを取得します。遅延ロードされたモジュール固有のルートをこのモジュール内で使用できるようにするため (BService に類似)、遅延ロードされた子モジュールには異なる構成を使用します。

static forChild(routes: Routes): ModuleWithProviders {
    return {
        ngModule: RouterModule, 
        providers: [{provide: ROUTES, multi: true, useValue: routes}]
    };
}

おすすめ記事