在Angular ReplaySubject中的Observable中发生所有更改后,只执行一次方法

时间:2017-09-30 08:57:12

标签: rxjs angular2-services

我创建了一个服务,用于检查父组件中的更改并向子组件发送通知。

以下是简单的服务。

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);
    }
}

Clouding类看起来像这样:

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

现在在父组件中,此类在构造函数中初始化,其变量将根据不同的方法而更改。 例如:

// 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);

在子组件中,我这样做是为了获得混浊的新值。

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-26"}
Clouding {cameraName: "Benjamin2", cloudDate: "2017-08-24"}

我的问题是,有没有办法让控制台只打印最后一次更改,即

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

并忽略发生的第一个更改。我不希望每次对象更改时都执行一个方法,只需在订阅了所有更改后执行。

希望问题很明确。

1 个答案:

答案 0 :(得分:1)

听起来你需要第三个按钮才能触发声明,将其从名称设置按钮和日期设置按钮中取出并将其放在新按钮上。

this.cloudingService.announceClouding(this.clouding);