Dan*_*chý 18 reactive-programming rxjs angular
我有对象流,我需要比较当前对象是否与以前相同,在这种情况下发出新值.我发现distinctUntilChanged操作符应该完全符合我的要求,但由于某种原因,除了第一个之外它永远不会发出值.如果我删除distinctUntilChanged值正常发出.
我的代码:
export class SettingsPage {
static get parameters() {
return [[NavController], [UserProvider]];
}
constructor(nav, user) {
this.nav = nav;
this._user = user;
this.typeChangeStream = new Subject();
this.notifications = {};
}
ngOnInit() {
this.typeChangeStream
.map(x => {console.log('value on way to distinct', x); return x;})
.distinctUntilChanged(x => JSON.stringify(x))
.subscribe(settings => {
console.log('typeChangeStream', settings);
this._user.setNotificationSettings(settings);
});
}
toggleType() {
this.typeChangeStream.next({
"sound": true,
"vibrate": false,
"badge": false,
"types": {
"newDeals": true,
"nearDeals": true,
"tematicDeals": false,
"infoWarnings": false,
"expireDeals": true
}
});
}
emitDifferent() {
this.typeChangeStream.next({
"sound": false,
"vibrate": false,
"badge": false,
"types": {
"newDeals": false,
"nearDeals": false,
"tematicDeals": false,
"infoWarnings": false,
"expireDeals": false
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
Meh*_*oha 23
我遇到了同样的问题,并使用JSON.stringify来比较对象:
.distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b))
肮脏但工作的代码.
Dan*_*chý 21
我终于找出问题所在.问题出在RxJS的版本中,在V4中,之前的参数顺序与V5不同.
RxJS 4:
distinctUntilChanged = function(keyFn,comparer)
RxJS 5:
distinctUntilChanged = function(comparer,keyFn)
在今天的每个文档中,您都可以找到V4参数命令,请注意!
从 RxJS v6+ 开始,有 distinctUntilKeyChanged
https://www.learnrxjs.io/operators/filtering/distinctuntilkeychanged.html
const source$ = from([
{ name: 'Brian' },
{ name: 'Joe' },
{ name: 'Joe' },
{ name: 'Sue' }
]);
source$
// custom compare based on name property
.pipe(distinctUntilKeyChanged('name'))
// output: { name: 'Brian }, { name: 'Joe' }, { name: 'Sue' }
.subscribe(console.log);
Run Code Online (Sandbox Code Playgroud)
您也可以包装原始distinctUntilChanged函数。
function distinctUntilChangedObj<T>() {
return distinctUntilChanged<T>((a, b) => JSON.stringify(a) === JSON.stringify(b));
}
Run Code Online (Sandbox Code Playgroud)
这让您可以像原始版本一样使用它。
$myObservable.pipe(
distinctUntilChangedObj()
)
Run Code Online (Sandbox Code Playgroud)
无论如何,当您的应用程序中有lodash时,您可以简单地使用lodash的isEqual()函数,该函数进行了深入的比较,并且与的签名完全匹配distinctUntilChanged():
.distinctUntilChanged(isEqual),
Run Code Online (Sandbox Code Playgroud)
或者,如果您有_空位(最近不建议这样做):
.distinctUntilChanged(_.isEqual),
Run Code Online (Sandbox Code Playgroud)
迈赫迪的解决方案虽然速度很快,但如果不维护订单,就无法工作。使用deep-equal或fast-deep-equal库之一:
.distinctUntilChanged((a, b) => deepEqual(a, b))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10506 次 |
| 最近记录: |