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

时间:2022-04-21 01:17:43

I have created a service which checks for changes in parent component and send notifications to the child component.

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

Below is the simple service.

以下是简单的服务。

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 class looks like this:

Clouding类看起来像这样:

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

Now in the parent component, this class is initialized in the constructor and its variables will change depending on different methods. Example:

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

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

The variables this.currentCloudName and this.currentCloudDate.cloudDate will change dynamically depending on button clicks.

变量this.currentCloudName和this.currentCloudDate.cloudDate将根据按钮点击动态变化。

When the buttons are clicked, I do:

单击按钮时,我会:

this.cloudingService.announceClouding(this.clouding);

In child component, I do this to get the new value of 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();
    }
}

Now on the console, I get the below when I click on a button in the parent:

现在在控制台上,当我点击父级中的按钮时,我得到以下内容:

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

My question is, is there a way to make console print only the last change i.e.

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

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

and ignore the first change that occurred. I dont want to do execute a method everytime the object changes, just execute after all changes have been subscribed.

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

Hope the question is clear.

希望问题很清楚。

1 个解决方案

#1


1  

It sounds like you need a third button to trigger the announce, take this off the name-setting button and date-setting button and put it on the new button.

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

this.cloudingService.announceClouding(this.clouding);

#1


1  

It sounds like you need a third button to trigger the announce, take this off the name-setting button and date-setting button and put it on the new button.

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

this.cloudingService.announceClouding(this.clouding);