2017-09-30 10 views
0

親コンポーネントの変更をチェックし、子コンポーネントに通知を送信するサービスを作成しました。Angular ReplaySubject Observableですべての変更が発生した後にメソッドを1回実行する

以下は簡単なサービスです。このクラスは、コンストラクタで初期化され、その変数は、異なる方法に応じて変化します、親コンポーネントで今

export class Clouding { 
    cameraName: string; 
    cloudDate: string; 
    cameraType: string; 
} 

import { Injectable } from '@angular/core'; 
import { ReplaySubject } from 'rxjs/ReplaySubject'; 
import { CloudDate } from './cloudDate'; 
import { Clouding } from './clouding'; 

@Injectable() 
export class CloudingService { 
    // Observable string sources 
    private cloudingAnnouncedSource = new ReplaySubject<Clouding>(1); 
    private cloudingConfirmedSource = new ReplaySubject<Clouding>(1); 

    // Observable string streams 
    cloudingAnnounced$ = this.cloudingAnnouncedSource.asObservable(); 
    cloudingConfirmed$ = this.cloudingConfirmedSource.asObservable(); 

    // Service message commands 
    announceClouding(clouding: Clouding) { 
     this.cloudingAnnouncedSource.next(clouding); 
    } 

    confirmClouding(clouding: Clouding) { 
     this.cloudingConfirmedSource.next(clouding); 
    } 
} 

曇クラスは次のようになります。 例:

// In constructor 
this.clouding = new Clouding(); 

// A method 
getCameras(): void { 
    this.clouding.cameraName = this.currentCloudName; 
} 

//Another method 
getCloudDates(): void { 
    this.clouding.cloudDate = this.currentCloudDate.cloudDate; 
} 

変数this.currentCloudNameとthis.currentCloudDate.cloudDateは、ボタンのクリックに応じて動的に変化します。ボタンがクリックされた

、私がやる:子コンポーネントで

this.cloudingService.announceClouding(this.clouding); 

を、私は曇りの新しい値を取得するには、これを行います。

Clouding {cameraName: "Benjamin2", cloudDate: "2017-08-26"} 
Clouding {cameraName: "Benjamin2", cloudDate: "2017-08-24"} 

私の質問があり、唯一の最後の変更、すなわちコンソールプリントを作るための方法があります:

import { Component, OnDestroy, Input, OnInit } from '@angular/core'; 
import { Clouding} from './clouding'; 
import { CloudingService } from './clouding.service'; 
import { Subscription } from 'rxjs/Subscription'; 

@Component({ 
    selector: 'app-images', 
    templateUrl: './images.component.html', 
    styleUrls: ['./images.component.css'] 
}) 

export class ImagesComponent implements OnDestroy, OnInit { 
    title = 'Images'; 
    @Input() 
    clouding: Clouding; 
    subscription: Subscription; 

    constructor(
     private cloudingService: CloudingService 
    ) { 
    } 

    ngOnInit(): void { 
     this.subscription = 
      this.cloudingService.cloudingAnnounced$.subscribe(
      clouding => { 
       this.clouding = clouding; 
       console.log(this.clouding); 
      }, 
      // The 2nd callback handles errors. 
      (err) => console.error(err), 
      // The 3rd callback handles the "complete" event. 
      () => { 
      } 
     ); 
     this.cloudingService.confirmClouding(this.clouding); 
    } 

    ngOnDestroy() { 
     // prevent memory leak when component destroyed 
     this.subscription.unsubscribe(); 
    } 
} 

は今、コンソール上で、私は私が親のボタンをクリックすると、以下の取得します

Clouding {cameraName: "Benjamin2", cloudDate: "2017-08-24"} 

発生した最初の変更を無視します。私は、オブジェクトが変更されるたびにメソッドを実行する必要はなく、すべての変更がサブスクライブされた後にただ実行します。

質問は明らかです。

+0

あなたは実際に観測可能なものを完成させることはありません。実際はそうではありません。完了前に '.last'を使用して最終値にアクセスすることができます。 – jonrsharpe

+0

私はそれを試みましたが、ボタンを再度クリックすると何も発表されません。 –

+0

はい、それは一度だけ起こることがあります。それがストリームの完成のポイントです。 – jonrsharpe

答えて

1

アナウンスをトリガーするには3番目のボタンが必要なようですが、これを名前設定ボタンと日付設定ボタンから取り出して新しいボタンに入れてください。

this.cloudingService.announceClouding(this.clouding); 
+0

ありがとう.....これは非常にうまくいった。 –

関連する問題