AngularJs 2 - несколько экземпляров созданного сервиса
Я создал услугу AngularJS 2 и использовал ее в двух разных компонентах: App-Component и Sub-Component. Каждое из них выводит свойство "log" (строка) моего сервиса.
Класс StateService:
@Injectable ()
class StateService {
public log : string;
static count : number = 0;
constructor () {
this.log = '';
StateService.count++;
this.writeToLog ('CREATED '+StateService.count+' at ' + new Date().toString());
}
public writeToLog (text : string) : void {
this.log += text + '\n';
}
}
Компонент:
@Component ({
selector : 'Sub-Component',
template : `<hr>
This is the Sub-Component !
<BR>
StateService Log :
<pre>{{ _stateService.log }}</pre>
<button (click)="WriteToLog ()">Write to log</button>
`,
providers : [StateService]
})
export class SubComponent {
constructor (private _stateService : StateService) {
}
public WriteToLog () : void {
this._stateService.writeToLog ('From Sub-Component - This is '+new Date().toString());
}
}
Живой пример кода здесь
Я за исключением того, что служба создается один раз, и когда каждый компонент вызывает метод WriteToLog, вывод одинаковый для каждого компонента, но это не так.
Пример вывода:
App-Component может выводить это:
Экземпляр 1 - Создано в Чт 21 Янв 2016 11:43:51
От App-Component - это Thu Jan 21 2016 11:43:54
От App-Component - это Thu Jan 21 2016 11:43:55
и Sub-Component может вывести это:
Экземпляр 2 - Создано в Чт 21 Янв 2016 11:43:51
От подкомпонента - это Thu Jan 21 2016 11:43:57
От подкомпонента - это Thu Jan 21 2016 11:43:58
Таким образом, создается 2 экземпляра службы (экземпляр 1 + экземпляр 2)
Мне нужен только один экземпляр;), и когда я добавляю строку в журнал, это должно появиться в обоих компонентах.
Спасибо за помощь
Ответы
Ответ 1
обновление Angular >= 2.0.0-RC.6
Не добавляйте службу поставщикам компонента.
Вместо этого добавьте его в
@NgModule({ providers: [...], ...
(модуля, который не ленивый загружен, потому что ленивые загружаемые модули вводят свою собственную область)
@Component ({
selector : 'Sub-Component',
template : `<hr>
This is the Sub-Component !
<BR>
StateService Log :
<pre>{{ _stateService.log }}</pre>
<button (click)="WriteToLog ()">Write to log</button>
`,
// providers : [StateService] <== remove
})
Angular & lt; = 2.0.0-RC.5
Если вы добавите его на компонент, вы получите новый экземпляр службы для каждого экземпляра компонента. Вместо этого добавьте его в
bootstrap(AppComponent, [StateService]);
У вас может быть более тонкое управление, добавив его в один компонент, затем этот компонент и все дети получат один и тот же экземпляр, но в противном случае приложение будет работать с экземпляром, созданным bootstrap()
. Это "иерархическая" в Angulars DI.
См. также
- http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html
- http://blog.thoughtram.io/angular/2015/09/17/resolve-service-dependencies-in-angular-2.html
Ответ 2
В дополнение к большому ответу Günter эта ссылка может дать более подробную информацию о том, как работает иерархическая инъекция зависимостей Angular2: