我一直在开发一个应用程序,允许一些不同的组件更新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);
}
答案 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.
}
}
}