2017-06-29 32 views
0

「無関係な」角2コンポーネントのサービスを作成することに本当に悩まされています。しかし、親子関係には問題はありません(バインディングまたはイベントエミッターを使用します)。データを運ぶ必要が親子ではない角2コンポーネントのサービスを作成する方法

  1. StatsService:

    は、私は3つのファイルを持っています。
  2. サッカーショットを生成するMatchBoardコンポーネント
  3. 画面にショット数を表示するStatsComponent。

しかし、私は数時間前からこれを処理してきましたが、公式の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); 
    } 
} 

、Iは「matchboardこの受信し得る:次いで、2(その後3、 4通常のように) ' MatchBoard comからポノント。 しかし、問題はStatsComponentで始まります。「subscribe」の直後に止まり、常に「0」だけ記録されます。

私はstatsComponentのどこかでonHomeTeamShot()を呼び出そうとしましたが、最初から常に「1」を表示していて、どちらも変更されません。

答えて

1

理由はStatsComponentで

providers: [StatsService] 

ラインです。つまり、StatsComponentにはサービスのインスタンスがあります。 解決策は、3つのコンポーネントの上にあるコンポーネントのプロバイダにプロバイダを置き、StatsComponentからそのラインを削除することです。

あなたはここでそれについていくつかのより多くの情報を見つけることができます:https://angular.io/guide/hierarchical-dependency-injection

+0

私はそれに気付かなかった... 12時間無駄になった... :)ありがとう!それは今働く。 –

1

はサービスにすべてのあなたのロジックをシフトし、重い物を持ち上げるを行うにはObservablesの力を活用します。

サービスでは、.interval()を使用してObservableを作成してください。これはあなたのポーリングの世話をします。既にSubjectを使用しているため、publishData()は必要ありません。

ngOnInit() { 
    this._statsService.generateShots() 
     .subscribe(shots => this.homeTeamShots = shots); 
    //this.homeTeamShots will increment from 0 to 1,2,3.... every 2000ms 
} 

そして、あなたのhomeTeamShots$Subjectに加入し、StatsComponentであなたのショットを表示するには:私は、単にgenerateShots()を購読するあなたのMatchBoardコンポーネントでカウントダウンを「開始」するために、今すぐ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. 
    } 

} 

という関数を作成しました:

ngOnInit() { 
    this._statsService.homeTeamShots$.subscribe(
     data => { 
      this.homeTeamShots = data; 
      console.log('Sibling2Component-received from sibling1: ' + data); 
     } 
    ); 
} 

そして、あなたは2つの成分単一の共有サービス(シングルトン)を介してデータを同期します。クリーン。

+0

ありがとう、私は反応的なものと角度の新しいですが、私はやって学ぶしようとする:)私は実際にサービスを介して物事を処理するためにアプリをやり直すだろう –

関連する問題