web-dev-qa-db-ja.com

Angular2-サービスを使用してコンポーネント間でデータを共有する

コンポーネント間でAngular2アプリに共有したいオブジェクトがあります。

最初のコンポーネントのソースは次のとおりです。

_/* app.component.ts */

// ...imports
import {ConfigService} from './config.service';

@Component({
    selector: 'my-app',
    templateUrl: 'app/templates/app.html',
    directives: [Grid],
    providers: [ConfigService]
})
export class AppComponent {
    public size: number;
    public square: number;

    constructor(_configService: ConfigService) {
        this.size = 16;
        this.square = Math.sqrt(this.size);

        // Here I call the service to put my data
        _configService.setOption('size', this.size);
        _configService.setOption('square', this.square);
    }
}
_

2番目のコンポーネント:

_/* grid.component.ts */

// ...imports
import {ConfigService} from './config.service';

@Component({
    selector: 'grid',
    templateUrl: 'app/templates/grid.html',
    providers: [ConfigService]
})
export class Grid {
    public config;
    public header = [];

    constructor(_configService: ConfigService) {
        // issue is here, the _configService.getConfig() get an empty object 
        // but I had filled it just before
        this.config = _configService.getConfig();
    }
  }
_

そして最後に私の小さなサービス、ConfigService:

_/* config.service.ts */

import {Injectable} from 'angular2/core';

@Injectable()
export class ConfigService {

    private config = {};

    setOption(option, value) {
        this.config[option] = value;
    }

    getConfig() {
        return this.config;
    }
}
_

データは共有されません。grid.component.tsでは、_configService.getConfig()行は空のオブジェクトを返しますが、app.component.tsの直前に入力されます。

私はドキュメントとチュートリアルを読みましたが、何も機能しませんでした。

私は何が欠けていますか?

ありがとう

[〜#〜] solved [〜#〜]

私の問題は、ConfigServiceを2回注入することでした。アプリケーションのbootstrap=と、それを使用しているファイル内。

providers設定を削除し、機能しました!

27
keversc

2つのコンポーネント内で定義します。したがって、サービスは共有されません。 AppComponentコンポーネント用のインスタンスとGridコンポーネント用のインスタンスがあります。

@Component({
  selector: 'my-app',
  templateUrl: 'app/templates/app.html',
  directives: [Grid],
  providers: [ConfigService]
})
export class AppComponent {
  (...)
}

簡単な解決策は、グリッドコンポーネントのproviders属性を削除することです...このようにして、サービスインスタンスはAppComponentとその子コンポーネントによって共有されます。

他の解決策は、対応するプロバイダーをbootstrap関数内に登録することです。この場合、インスタンスはアプリケーション全体で共有されます。

bootstrap(AppComponent, [ ConfigService ]);

なぜそうする必要があるのか​​を理解するには、Angular2の「階層インジェクター」機能に注意する必要があります。次のリンクが役立つ場合があります。

28

Angularの最新バージョンでは、サービスを共有したい場合、bootstrap関数に追加できません。通常の場合と同様に、NgModuleプロバイダーリストに追加するだけです。サービスの場合、デフォルトの動作はシングルトンになります。

bootstrap(AppComponent);

@NgModule({
    declarations: [
        ....
    ],
    imports: [
       ....     
    ],
    providers: [
        ConfigService,
....
6
Mike D

コンポーネントのConfigServiceprovidersを追加しないでください。これにより、すべてのコンポーネントに新しいインスタンスが作成されます。共通の親コンポーネントのprovidersに追加します。ルートコンポーネントまたはbootstrap(App, [ConfigService])に追加すると、アプリケーション全体が1つのインスタンスを共有します。

4