比较Angular中Observable的上一个值与下一个值 [英] Compare Observable's Previous Value With Next Value in Angular

查看:75
本文介绍了比较Angular中Observable的上一个值与下一个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在开发一个App,该App允许一些不同的组件更新Angular中的 BehaviorSubject .在每个组件中,我存储以前的 BehaviorSubject 值的本地副本.为了知道组件是否产生了新的价值,我打算使用LoDash的 _.isEqual()函数比较两个对象.但是我发现在进行比较之前,我的Observable本地副本已经更新.

I have been working on an App that allows a few different components to update a BehaviorSubject in Angular. Within each component I store a local copy of the previous BehaviorSubject value. In order to know whether or not the component generated the new value being pushed out I was planning on just comparing the two objects using LoDash's _.isEqual() function. However I am finding that my local copy of the Observable has already been updated before the comparison can take place.

Angular是否在 = 语句中查找并在Observable next 函数之外创建对该组件属性的外部绑定?

Does Angular look for = statements and create an external binding to that component property outside of the Observable next function?

给出下面的代码,我发现我组件中的 this.QueryParams 属性已更新为函数中正在处理的当前值,即使我没有进行比较,也导致我的比较失败将新值分配给属性,直到评估 if 语句为止.

Given the code below I am finding that my this.QueryParams property within the component has been updated to the current value being processed in the function, causing my comparison to fail even though I don't assign the new value to the property until the if statement has been evaluated.

组件

export class LogsModalComponent implements OnInit {

    private QueryParams: LogsQueryParameters

    ngOnInit() {

        this._LogsService.QueryParameters$.subscribe(_QueryParams => {
            console.log(this.QueryParams);
            console.log(_QueryParams);

            if (!_.isEqual(this.QueryParams, _QueryParams) {
                this.QueryParams = _QueryParams;

                // Some code to process if the new value was different.
            }
        }
    }

    updateStartDate() {
        this.QueryParams.filterStartDate = _.isUndefined(this.FilterStartDate) ? NaN : new Date(this.FilterStartDate.nativeElement.value).getTime();
        this._LogsService.updateQueryParams(this.QueryParams);
}
}

服务

    LogsQueryParameters: BehaviorSubject<LogsQueryParameters> = new BehaviorSubject<LogsQueryParameters>({
            limit: 25,
            logLevels: "",
            logTypes: "",
            logUserIDs: "",
            filterStartDate: NaN,
            filterEndDate: NaN
        })
        LogsQueryParameters$ = this.LogsQueryParameters.asObservable();

    updateQueryParams(QueryParams) {
        this.LogsQueryParameters.next(QueryParams);
    }

推荐答案

RxJS可观察对象具有方法

RxJS observables have a method distinctUntilChanged() that returns a new observable that only emits a new value if it is different from the previously emitted value:

this._LogsService.QueryParameters
    .distinctUntilChanged()
    .subscribe((_QueryParams) => this.QueryParams = _QueryParams);

这适用于简单比较.如果仍然需要 _.isEqual 函数,则可以将回调传递给 distinctUntilChanged()来执行比较:

This works for simple comparisons. If you need the _.isEqual function nonetheless, you can pass a callback to distinctUntilChanged() to perform the comparison instead:

this._LogsService.QueryParameters
    .distinctUntilChanged((prev, curr) => _.isEqual(prev, curr))
    .subscribe((_QueryParams) => this.QueryParams = _QueryParams);

请注意,您不会返回!... 在回调中,只要返回值是 false (意味着被测值不等于),值就会通过.

Note that you don't return ! ... inside the callback, whenever the return value is false (meaning the value under test is not equal), the value passes.

更新

从最新的编辑看来,您实际上实际上是在绕过完全相同的对象,并且仅更改了其内容,如@Brandon在下面的注释中建议的那样.您可以尝试在更新时通过 Object.assign()创建一个新对象:

From your latest edit it looks like you're actually passing around the exact same object, and only mutating its contents, as @Brandon suggested in the comment below. You could try creating a new object when updating, through Object.assign():

updateStartDate() {
    this.QueryParams.filterStartDate = _.isUndefined(this.FilterStartDate)
        ? NaN 
        : new Date(this.FilterStartDate.nativeElement.value).getTime();
    this._LogsService.updateQueryParams(Object.assign({}, this.QueryParams));
}

对象实际上是通过引用传递的.

请注意, new Date()还会返回一个对象.该对象也通过引用进行传递和分配,只是这次 Object.assign 不会帮到您,因为日期对象取决于原型链接(不是 plain 对象).

Note that new Date() also returns you an object. That object is passed and assigned by reference as well, only this time Object.assign won't help you out, since the date object depends on prototype linkage (it's not a plain object).

这篇关于比较Angular中Observable的上一个值与下一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆