私のアプリケーションでは、1つのアプリケーションで2つの異なるbootstrapモジュール(@NgModule
)が独立して実行されています。 angular appビットで分離されたbootstrapモジュールは1つではなく、相互に通信してデータを共有する必要があります。
モジュールのプロバイダーとして@Injectable
サービスを通じて、@NgModule
の下のすべてのコンポーネントでデータを共有できますが、2つの異なるモジュール(モジュール内のコンポーネントではない)間でデータを共有する方法を知っています。
別のモジュールで1つのサービスオブジェクトにアクセスする方法はありますか?ブラウザのメモリで利用可能なサービスのオブジェクトにアクセスし、他のangularモジュールで使用する方法はありますか?
Angularの外部でサービスをインスタンス化し、値を提供できます。
class SharedService {
...
}
window.sharedService = new SharedService();
@NgModule({
providers: [{provide: SharedService, useValue: window.sharedService}],
...
})
class AppModule1 {}
@NgModule({
providers: [{provide: SharedService, useValue: window.sharedService}],
...
})
class AppModule2 {}
1つのアプリケーションがSharedService
の状態を変更するか、Observable
に値を発行させるメソッドを呼び出し、サブスクライバーがエミッターとは異なるアプリケーションにある場合、サブスクライバーのコードはエミッターのNgZone
で実行されます。
したがって、SharedService
のobservableにサブスクライブする場合に使用します
class MyComponent {
constructor(private zone:NgZone, private sharedService:SharedService) {
sharedService.someObservable.subscribe(data => this.zone.run(() => {
// event handler code here
}));
}
}
Angular2コンポーネントとしてbootstrapモーダルを動的に作成する方法? も参照してください。
Angular 2の最終バージョンでは、モジュールによって提供されるサービスは、それをインポートする他のすべてのモジュールで利用できます。 Official Style Guide アプリケーション全体のどこでも再利用されるアプリケーション全体のサービス(シングルトン)は、いくつかのCore Module
によって提供されるべきであり、メインのApp Module
にインポートされるため、注入可能になるどこにでも。
共有シングルトンを持つコアモジュールを含む構造を使用せず、2つのNgModuleを独立して開発しており、一方のサービスを他方で使用する場合、唯一の解決策はプロバイダーを他:
プロバイダーモジュールは次のとおりです。
/// some.module.ts
import { NgModule } from '@angular/core';
import { SomeComponent } from './some.component';
@NgModule({
imports: [],
exports: [],
declarations: [SomeComponent],
providers: [ MyService ], // <======================= PROVIDE THE SERVICE
})
export class SomeModule { }
MyService
を使用したい他のモジュールは次のとおりです。
/// some-other.module.ts
import { NgModule } from '@angular/core';
import { SomeModule } from 'path/to/some.module'; // <=== IMPORT THE JSMODULE
import { SomeOtherComponent } from './some.other.component';
@NgModule({
imports: [ SomeModule ], // <======================== IMPORT THE NG MODULE
exports: [],
declarations: [SomeOtherComponent],
providers: [],
})
export class SomeOtherModule { }
このように、サービスはSomeOtherModule
宣言のコンポーネントおよびSomeModule自体に注入可能である必要があります-コンストラクターで要求するだけです:
/// some-other.module.ts
import { MyService } from 'path/to/some.module/my-service';
/* ...
rest of the module
*/
export class SomeOtherModule {
constructor( private _myService: MyService) { <====== INJECT THE SERVICE
this._myService.dosmth();
}
}
それでも問題が解決しない場合は、再定式化してください。
共有モジュールを作成する
@NgModule({})
export class SharedModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: SharedModule,
providers: [SingletonService]
};
}
}
アプリモジュールには、親アプリモジュールがそのような共有モジュールをインポートします
SharedModule.forRoot()
共有モジュールをインポートする必要がある場合は、子モジュール
SharedModule
https://angular-2-training-book.rangle.io/handout/modules/shared-modules-di.html
この回答のアイデアを使用して、angularアプリケーション内の複数のブートストラップモジュール間でデータを共有しようとしました。私が興味を持っていたデータは、http.get()呼び出しからのものでした。高価な呼び出しでしたので、呼び出しを1回だけ行い、その結果を2つのブートストラップされたモジュール間で共有したかったのです。
最初に、提案されたようにグローバルウィンドウオブジェクトのプロパティとしてサービスを保存しましたが、最終的に、静的変数を使用し、observableでpublishReplay()を呼び出してReplaySubjectを作成し、将来のサブスクライバーに放出を再生することにしました。これにより、複数のサブスクライバーがデータを共有し、REST呼び出しを1回だけ行うことができました。
ここで1つの警告...元の質問は1つのサービスを共有する方法を尋ねました...この回答は1つのサービスを共有しません...複数のサービスが作成されますが、オブザーバブルが静的変数に格納されるためデータが共有されます...つまり、オブザーバブルは、アプリケーションとpublishReplay()
の呼び出しのために、オブザーバブルにサブスクライブしているユーザーが以前に返されたデータをリプレイする限り保持されます。
ここに私のコードがあります:
import { Injectable } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs/Rx';
import { Http } from '@angular/http';
@Injectable()
export class InitService {
static observable: Observable<number> = null;
constructor(private http: Http) {}
getInitData(): Observable<number> {
if (InitService.observable == null) {
InitService.observable = this.http.get('api/Init')
.map(this.extractData)
.publishReplay()
.refCount()
.catch(this.handleError);
}
return InitService.observable;
}
extractData(res: Response) {
let body: any = res.json();
return body || {};
}
}
お役に立てれば。
GünterZöchbauerの答えは素晴らしいですが、あなたが抱えているかもしれない問題の1つは
window.sharedService
typeScriptでエラーが発生します。これを回避するには、すべてのインスタンスを置き換えます
window.sharedService
と
(<any>window).sharedService