Как правильно обмениваться служебными данными между компонентами в Angular 2

Я хочу создать сервис, чтобы получать данные из файла.json один раз и делиться ими с несколькими подписчиками. Но теперь с моим решением количество запросов на получение данных из файла.json равно количеству подписчиков для моего сервиса.

getconfig.service.ts

import {Injectable} from 'angular2/core';
import {Http, Response} from "angular2/http";

@Injectable()
export class ConfigService {
    config: any;
    http: Http;

    constructor(http: Http) {
        this.http = http;
        console.log('Inside service');
        this.config = this.http.get('/config.json');
    }

}

robotui.component.ts

...
import {ConnectionService} from '../services/connection.service';

@Component({
  ...
  providers: [HTTP_PROVIDERS, ConfigService, ConnectionService]
  ...
})

constructor(private _configService: ConfigService) {
  this._configService.config.subscribe((observer) => {
    console.log('Subscribe in RobotUI component', JSON.parse(observer._body));
  });
}

actual.photo.component.ts

import {Component} from 'angular2/core';
import {ConfigService} from '../services/getconfig.service';

@Component({
  ...
  providers: [ConfigService]
})

export class ActualPhotoComponent {

  constructor(private _configService: ConfigService) {
    this._configService.config.subscribe((observer) => {
      console.log('Subscribe in ActualPhoto component', JSON.parse(observer._body));
    });
  }

}

Когда я запускаю его в своей консоли, я вижу:

Итак, есть запрос get для каждого подписчика. Мне нужно решение, когда я получаю файл config.json только один раз, сохраняю эту информацию в сервисе и делюсь ею с несколькими подписчиками.

1 ответ

Решение

Это потому что

@Component({
  ...
  providers: [ConfigService]  //<--- this creates service instance per component
})

Чтобы обмениваться данными между контроллерами / компонентами и создавать только один экземпляр, вы должны внедрить свой сервис в bootstrap function,

import {ConfigService } from './path to service';

bootstrap('AppCompoent',[configService])  //<----Inject here it will create a single instance only

В подписке компонента,

robotui.component.ts

...
import {ConfigService} from '../services/getconfig.service';  //<----- Note this line here....
import {ConnectionService} from '../services/connection.service';

@Component({
  ...
  ...  // No providers needed anymore
  ...
})

constructor(private _configService: ConfigService) {
  this._configService.config.subscribe((observer) => {
    console.log('Subscribe in RobotUI component', JSON.parse(observer._body));
  });
}

actual.photo.component.ts

import {Component} from 'angular2/core';
import {ConfigService} from '../services/getconfig.service';

@Component({
  ...
  ...  // No providers needed anymore...
})

export class ActualPhotoComponent {

  constructor(private _configService: ConfigService) {
    this._configService.config.subscribe((observer) => {
      console.log('Subscribe in ActualPhoto component', JSON.parse(observer._body));
    });
  }

}

Это то, что вы должны сделать.

Другие вопросы по тегам