我真的很难为“无关的”Angular 2组件创建服务 . 但是,父子关系没有问题(我使用绑定或事件 Launcher ) .
我有3个文件:
-
StatsService应该携带数据 .
-
MatchBoard组件,用于生成足球镜头
-
StatsComponent可以在屏幕上打印拍摄张数 .
但是我已经阅读了官方的A2文档并且仍然无法找到解决方案,因此我已经处理了几个小时了 .
我想要的是:我只想生成镜头(每2秒),用服务 grab 它们并发送到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 received this: 2 (then 3, then 4 like normal)' . 但问题始于StatsComponent - 它在'subscribe'之后立即卡住并且始终只记录'0' .
我尝试在statsComponent中的某个地方调用onHomeTeamShot(),但它从一开始就一直显示“1”并且也不会改变 .
2 回答
原因是这条线
在StatsComponent中 . 这意味着StatsComponent拥有自己的服务实例 . 解决方案是让组件中的提供程序仅在三个组件之上,并从StatsComponent中删除该行 .
你可以在这里找到更多相关信息:https://angular.io/guide/hierarchical-dependency-injection
将所有逻辑转移到服务上,并利用
Observables
的强大功能来完成繁重的工作 .在您的服务中,使用
.interval()
创建一个Observable . 这将照顾您的投票 . 您甚至不需要publishData()
,因为您已经在使用Subject
. 我创建了一个名为generateShots()
的函数现在,要
MatchBoard
组件中的"start"倒计时,只需订阅generateShots()
:要在
StatsComponent
中显示您的镜头,请订阅您的homeTeamShots$
Subject
:瞧,您有两个组件通过单个共享服务(单例)同步数据 . 清洁 .