web-dev-qa-db-ja.com

Angular router:遅延読み込みモジュールにデータを渡す方法は?

私のAngularアプリのモジュール用のルーティングパスは次のとおりです。

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'documents',
                data: { myObject: MyConstants.OPTION_ONE },
                children: [
                    {
                        path: ':ID_DOC',
                        children: [
                            { path: 'edit', component: EditDocumentComponent },
                            { path: '', component: DocumentDetailsComponent },
                        ]
                    },
                    { path: 'add', component: AddDocumentComponent },
                    { path: '', component: DocumentsListComponent }
                ]
            }
        ])
    ],
    exports: [
        RouterModule
    ]
})

export class DocumentsManagementRoutingModule {
}

ご覧のとおり、dataプロパティを使用して「ドキュメント」内のすべてのパスにデータを渡すため、ルーティングパスで宣言されたコンポーネントのいずれかから取得できます。

たとえば、DocumentDetailsComponentでデータを取得する方法は次のとおりです。

export class DocumentDetailsComponent implements OnDestroy {
    private obsData: Subscription;
    private option: any;

    constructor(private route: ActivatedRoute) {
        this.obsData = this.route.data.subscribe(data => {
            this.option = data['myObject'];
        });
    }

    ngOnDestroy(): void {
        this.obsData.unsubscribe();
    }
}

ここで、アプリ全体のルーティング構造を変更し、loadChildren属性を使用して、遅延読み込みで他のモジュールから上記のモジュールを呼び出します。そして、同じ方法でデータを渡します。

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'users',
                loadChildren: 'app/documents/documents.module#DocumentsModule',
                data: { myObject: MyConstants.OPTION_ONE }},
            {
                path: ':ID_USER',
                children: [
                    { path: 'edit', component: EditUserComponent },
                    { path: '', component: UserDetailsComponent },
                ]
            },
            { path: 'add', component: AddUserComponent },
            { path: '', component: UserListComponent }
        ])
    ],
    exports: [
        RouterModule
    ]
})

export class UsersManagementRoutingModule {
}

そして、必要に応じて、DocumentsManagementRoutingModuleを呼び出す他のすべてのモジュールについても同じことを行い、myObjectプロパティをMyConstants.OPTION_TWOMyConstants.OPTION_THREEなどに変更しました。

次に、遅延読み込みモジュールを呼び出すモジュールとその関連パスがわからないので、呼び出し元モジュールからdataプロパティを取得する方法は?

17
smartmouse

ActivateRoute.pathFromRootを使用して親ルートをトラバースし、それを利用できる最も近い祖先からデータを取得できます。このような何かが動作するようです:

  ngOnInit(): void {
    let idx = this.activatedRoute.pathFromRoot.length - 1;
    while(this.sharedData == null && idx > 0){
      this.sub = this.activatedRoute.pathFromRoot[idx].data.subscribe(subData => {

        if(subData.id)
          this.sharedData = subData;

        console.log('shared data', this.sharedData);
      });
      idx--;
    }
  }

https://plnkr.co/edit/K5Rb1ZvTvSQNM6tOLeFp

6
rusmus

私は質問が何について尋ねているのか理解できると思います。


問題

提供されているプラ​​ンカー@smartmouseのルーティンググラフは次のとおりです。

- home
  - shop
  - contact
    - map
  - about

dataルート構成で構成されたhomeオブジェクトがあります。直接の子ルートはこのデータオブジェクトにアクセスできます。問題は、非直接の子mapdataオブジェクトにアクセスしたいが、明らかにアクセスできないことです。

そして、@ smartmouseがさらにプッシュすることを望んでいることを知ることができます-ネストされた非直接の子ルートは祖先のデータにアクセスできます。

なぜできないのですか?

変更したプランカーを参照してください。 https://plnkr.co/edit/FA7mGmspUXHhU8YvgDpT

DefaultComponentに追加の子コンポーネントcontactを定義していることがわかります。これは、ルートcontactの直接のデフォルトの子であることを示しています。これは、上位ルートhomeの直接の子でもあると解釈できます。そのため、dataオブジェクトにアクセスできます。

溶液

私から提供されたプランカーをもう一度見てください。

注:Angular私が使用しているパッケージはv4.3.0です

アプローチ#1-クエリパラメーター

contactルートのhome.component.tsでいくつかのクエリパラメーターを定義します。使い方を見ることができます。

長所

  • あらゆるレベルのルートでクエリパラメータにアクセスできます。
  • lazyloadモジュールとうまく機能します

短所

  • ルート設定でクエリパラメータを定義することはできません。

    しかし、いくつかのルートライフサイクルフックを使用して、ターゲットの先祖ルート用にそれらを定義することができます

アプローチ#2-サービス

シングルトンパターンとして再生するアプリケーションのトップレベルでデータ共有サービスを定義します。また、utilを使用して、2回開始されないようにします。次に、そこにデータを入れて、どこからでも取得できます。

長所

  • dI経由でグローバルに表示。
  • lazyloadモジュールとうまく機能します

短所

  • ルート設定でデータを更新することはできません。
  • 別の場所でデータを定義する必要があります。ソースを制御できない場合は、問題がある可能性があります。

アプローチ#3-ルート解決

誰かが、プランカーでresolveサンプルコードも定義していることに気付くかもしれません。ルート設定のdataと同じ動作をすることを示すためですが、実際には動的なデータ取得用です。

https://vsavkin.com/angular-router-understanding-router-state-7b5b95a12eab#54
dataプロパティは、アクティブ化されたルートに固定オブジェクトを渡すために使用されます。アプリケーションの存続期間を通じて変化することはありません。 resolveプロパティは、動的データに使用されます。

@smartmouseのplunkrを例として取り上げます。

'home'ルート設定でdataが定義されています。連絡先のデフォルトルートのContactModuleにデータリゾルバーを定義し、上位ルートから渡されたデータをプロキシできます。その後、すべての直接の子ルートはresolvedデータオブジェクトにアクセスできます。

長所

  • ネストされたルートのどのレベルでもうまく機能します
  • lazyloadモジュールとうまく機能します

短所

  • 子ルートがそのデータにアクセスしたいすべての親ルートでその解決プロパティを宣言する必要がある場合があります。それは一種の汚い仕事です。

現在のところ、Angularの一般的な使用法を備えた完璧で普遍的なソリューションはありません。誰かが長所と短所を比較検討し、適切なものを選択する必要があります。

10
e-cloud

サービスを使用して、モジュールまたはコンポーネント間でデータを共有してみませんか。このサービスをメインモジュールプロバイダーでインポートして、他のすべてのモジュール(遅延読み込みモジュール)で使用し、データを共有できます。

サービスには値を設定および取得する関数を含めることができるため、サービスでこれらの関数を使用して必要なデータを取得できます

0
Kowsalya
@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: 'users',
                loadChildren: 'app/documents/documents.module#DocumentsModule',
                resolve : {
                     data: DataResolver
                }
            {
        ])
    ],
    exports: [
        RouterModule
    ]
})

export class UsersManagementRoutingModule {
}


@Injectable()
export class DataResolverimplements Resolve<Data> {
  resolve() {
    return this.serice.getData();
  }
}
0