比较Observable的上一个值与Angular中的下一个值

时间:2017-09-13 17:20:46

标签: angular typescript rxjs lodash observable

我一直在开发一个应用程序,允许一些不同的组件更新Angular中的BehaviorSubject。在每个组件中,我存储了先前BehaviorSubject值的本地副本。为了知道组件是否生成了新值被推出,我计划仅使用LoDash的_.isEqual()函数比较两个对象。但是我发现Observable的本地副本已经更新,然后才能进行比较。

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

根据下面的代码,我发现组件中的this.QueryParams属性已更新为函数中正在处理的当前值,导致我的比较失败,即使我没有指定新的在评估if语句之前对属性赋值。

组件

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

2 个答案:

答案 0 :(得分:5)

RxJS observables有一个方法distinctUntilChanged(),它返回一个新的observable,如果它与先前发出的值不同,则只发出一个新的值:

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

这适用于简单的比较。如果您仍需要_.isEqual功能,则可以将回调传递给distinctUntilChanged()以执行比较:

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

请注意,只要返回值为! ...(意味着测试中的值不等于),您就不会在回调中返回false,值< EM>通过

<强>更新

从你最新的编辑中看起来你实际上正在传递完全相同的对象,并且只改变其内容,正如@Brandon在下面的评论中所建议的那样。您可以尝试在更新时通过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不会帮助你,因为date对象依赖于原型链接(它不是 plain 对象)。 / p>

答案 1 :(得分:1)

对于那些想要将先前值与 Observable(或 BehaviourSubject)的当前值进行比较的人,只需使用 pairwise 运算符。例如:

ngOnInit() {
    this._logsService.yourObservable$.pipe(pairwise()).subscribe(([previous, current]) => {
        if (previous !== current) {
            // Some code to process if the new value was different.
        }
    }
}