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);
}
}
и второй компонент:
/* 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.
Я читал документы и учебники, ничего не работало.
Что мне не хватает?
Спасибо
решаемые
Моя проблема заключалась в том, что я дважды вводил свой ConfigService. В бутстрапе приложения и в файле, где я его использую.
Я удалил настройку providers
и ее сработает!
Ответы
Ответ 1
Вы определяете его в своих двух компонентах. Таким образом, услуга не используется. У вас есть один экземпляр для компонента AppComponent
, а другой - для компонента Grid
.
@Component({
selector: 'my-app',
templateUrl: 'app/templates/app.html',
directives: [Grid],
providers: [ConfigService]
})
export class AppComponent {
(...)
}
Быстрое решение заключается в удалении атрибута providers
для вашего компонента Grid... Таким образом экземпляр службы будет совместно использоваться AppComponent
и его дочерними компонентами.
Другим решением является регистрация соответствующего провайдера в функции bootstrap
. В этом случае экземпляр будет совместно использоваться всем приложением.
bootstrap(AppComponent, [ ConfigService ]);
Чтобы понять, зачем вам это нужно, вам нужно знать о функции "иерархических инжекторов" Angular2. Следующие ссылки могут быть полезны:
Ответ 2
Для последней версии angular, если вы хотите поделиться службой, вы не можете добавить ее в функцию начальной загрузки. Просто добавьте его в список поставщиков NgModule, как и обычный сервис, его поведение по умолчанию будет однострочным.
самозагрузки (AppComponent);
@NgModule({
declarations: [
....
],
imports: [
....
],
providers: [
ConfigService,
....
Ответ 3
Не добавляйте ConfigService
к providers
вашего компонента. Это приводит к появлению новых экземпляров для каждого компонента.
Добавьте его в providers
общего родительского компонента. Если вы добавите его в корневой компонент или bootstrap(App, [ConfigService])
, ваше приложение будет иметь один экземпляр.