我真的很难为“无关的”Angular 2组件创建服务。但是,父子关系没有问题(我使用绑定或事件发射器)。
我有3个文件:
但是我已经阅读了官方的A2文档并且仍然无法找到解决方案,因此我已经处理了几个小时了。
我想要的是:我只想生成镜头(每2秒),用服务抓住它们并发送到StatsComponent,以便它显示屏幕上的镜头数量。那很简单。
StatsService组件
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class StatsService {
private homeTeamShots = new Subject<any>();
homeTeamShots$ = this.homeTeamShots.asObservable();
publishData(data:any){
this.homeTeamShots.next(data);
}
}
MatchBoard组件
import { Component, Input, OnInit, OnChanges } from '@angular/core';
import {StatsService} from '../stats.component/stats.service';
@Component({
selector: 'match-board',
templateUrl: './matchboard.component.html',
styleUrls: ['./matchboard.component.css']
})
export class MatchBoard implements OnChanges {
homeTeamShots:number = 0;
constructor(private _statsService:StatsService) {
this._statsService.homeTeamShots$.subscribe(
data => {
console.log('matchboard received this: ' + data);
}
)
}
ngOnChanges(){
}
onHomeTeamShot(){
this.homeTeamShots += 1;
this._statsService.publishData(this.homeTeamShots);
}
ngOnInit(){
// shots are taken every 2 seconds as a example
setInterval(()=> this.onHomeTeamShot(), 2000);
}
}
和StatsComponent
import { Component, Input, OnInit, OnChanges } from '@angular/core';
import {StatsService} from '../stats.component/stats.service';
@Component({
selector: 'stats',
templateUrl: './stats.component.html',
styleUrls: ['./stats.component.css'],
providers: [StatsService]
})
export class StatsComponent implements OnChanges {
homeTeamShots:number;
constructor(private _statsService:StatsService) {
this.homeTeamShots = 0;
this._statsService.homeTeamShots$.subscribe(
data => {
this.homeTeamShots = data;
console.log('Sibling2Component-received from sibling1: ' + data);
}
);
}
ngOnChanges(){
}
onHomeTeamShot() {
this.homeTeamShots += 1;
console.log('number of shots in stats now ' + this.homeTeamShots);
this._statsService.publishData(this.homeTeamShots);
}
ngOnInit(){
setInterval(()=> console.log(this.homeTeamShots), 2050);
}
}
在控制台中,我得到'matchboard收到了这个:来自MatchBoard组件的2(然后是3,然后是4正常)'。 但问题始于StatsComponent - 它在'subscribe'之后被卡住并且一直只记录'0'。
我尝试在statsComponent中调用onHomeTeamShot(),但它从头开始一直显示“1”,也不会改变。
答案 0 :(得分:1)
原因是行
providers: [StatsService]
StatsComponent中的。这意味着StatsComponent拥有自己的服务实例。 解决方案是让组件中的提供程序仅在三个组件之上,并从StatsComponent中删除该行。
您可以在此处找到有关此内容的更多信息:https://angular.io/guide/hierarchical-dependency-injection
答案 1 :(得分:1)
将所有逻辑转移到服务上,并利用Observables
的力量来完成繁重的工作。
在您的服务中,使用.interval()
创建一个Observable。这将照顾您的投票。您甚至不需要publishData()
,因为您已经在使用Subject
。我创建了一个名为generateShots()
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs/Subject';
@Injectable()
export class StatsService {
private homeTeamShots = new Subject<any>();
homeTeamShots$ = this.homeTeamShots.asObservable();
generateShots() {
return Observable.interval(2000)
.map(ticks => this.homeTeamShots$.next(ticks));
//.interval() returns a single integer, starting from 0,1,2....
//just simply update your subject with that value.
}
}
现在,要在MatchBoard
组件中“开始”倒计时,只需订阅generateShots()
:
ngOnInit() {
this._statsService.generateShots()
.subscribe(shots => this.homeTeamShots = shots);
//this.homeTeamShots will increment from 0 to 1,2,3.... every 2000ms
}
要在StatsComponent
中显示您的镜头,请订阅homeTeamShots$
Subject
:
ngOnInit() {
this._statsService.homeTeamShots$.subscribe(
data => {
this.homeTeamShots = data;
console.log('Sibling2Component-received from sibling1: ' + data);
}
);
}
瞧,您有两个组件通过单个共享服务(单例)同步数据。干净。