为什么没有 RxJS 运算符来从流中删除特定项目?
Why is there no RxJS operator to remove specific items from a stream?
我在尝试从可观察流中删除 属性 时遇到了难以置信的困难。我有一个 Observable,它在 url(angular 的 ActivatedRoute.queryParams
)中发出查询参数对象。我正在尝试从发出的值中删除键和值并调用 distinctUntilChanged()
以便它们的更改不会触发我的观察者。
pluck()
允许您只允许流中的一个参数通过,filter()
允许您过滤整个流,skip()
运算符允许您跳过整个流发射,throttle()
来限制排放量。尽管做与 pluck()
相反的事情——你希望允许流中除一个值以外的所有值都通过——并不存在。最接近完成它的是一个 map(),它创建一个新对象,删除 属性,然后 returns 那个新对象,但这充其量只是小故障,而且通常是行不通的。
除了我试图忽略的参数属性之外,我已经求助于为所有查询参数属性创建单独的订阅。我想必须有更好的方法来解决这个问题,是否有一些我缺少或解决的神奇运算符?当 pluck()
之类的东西存在时,为什么反应库中缺少如此明显的运算符?
编辑:
代码:
this.activatedRoute.queryParams
.map((value) => {
const newObj = Object.assign({}, value);
delete newObj['page'];
return newObj;
})
.distinctUntilChanged()
.skip(1)
.subscribe(
(value) => console.log(value)
);
您的代码不起作用的原因似乎是具有相同属性和值的对象在 JavaScript 中不被视为相等,因此 distinctUntilChanged
不起作用,因为
{prop: "value"} === {prop: "value"}
是 false
.
有一个简单的解决方案。不推荐用于长列表等,因为它在负载下表现不佳,但如果只是路由更改,那不会很快更改很多次。
this.activatedRoute.queryParams
.map((value) => {
// Your existing code or
const {page, ...otherProps} = value;
return otherProps;
})
// You tell it what to use as comparison
.distinctUntilChanged((oldProps, newProps) =>
JSON.stringify(oldProps) === JSON.stringify(newProps)
)
// Not sure you still need this
.skip(1)
.subscribe(
(value) => console.log(value)
);
您可以在 Object comparison in JavaScript 中阅读更多比较对象的方法。
更新:
这个答案被否决了,因为据说 JSON.stringify()
有时会以不同的顺序提供属性。
JSON.stringify()
的细节并不是真正答案的核心,这就是为什么我链接到另一个专注于对象比较的 SO 答案,但是,简单的谷歌搜索显示了另一个你可以使用的答案:
sort object properties and JSON.stringify
为了跟随答案,您更改此位:
.distinctUntilChanged((oldProps, newProps) =>
JSON.stringify(oldProps) === JSON.stringify(newProps)
)
变成类似这样的东西:
.distinctUntilChanged((oldProps, newProps) => {
// You can put this at the beginning of the file
// It doesn't need to live inside the RxJS operator
const createComparisonString =
(obj) => JSON.stringify(obj, Object.keys(obj).sort());
return createComparisonString(oldProps) === createComparisonString(newProps);
})
但是,JSON.stringify
并不是比较对象的唯一方法。如果您愿意,请参阅上面引用的答案以获取其他选项的示例。再次 Object comparison in JavaScript.
我在尝试从可观察流中删除 属性 时遇到了难以置信的困难。我有一个 Observable,它在 url(angular 的 ActivatedRoute.queryParams
)中发出查询参数对象。我正在尝试从发出的值中删除键和值并调用 distinctUntilChanged()
以便它们的更改不会触发我的观察者。
pluck()
允许您只允许流中的一个参数通过,filter()
允许您过滤整个流,skip()
运算符允许您跳过整个流发射,throttle()
来限制排放量。尽管做与 pluck()
相反的事情——你希望允许流中除一个值以外的所有值都通过——并不存在。最接近完成它的是一个 map(),它创建一个新对象,删除 属性,然后 returns 那个新对象,但这充其量只是小故障,而且通常是行不通的。
除了我试图忽略的参数属性之外,我已经求助于为所有查询参数属性创建单独的订阅。我想必须有更好的方法来解决这个问题,是否有一些我缺少或解决的神奇运算符?当 pluck()
之类的东西存在时,为什么反应库中缺少如此明显的运算符?
编辑:
代码:
this.activatedRoute.queryParams
.map((value) => {
const newObj = Object.assign({}, value);
delete newObj['page'];
return newObj;
})
.distinctUntilChanged()
.skip(1)
.subscribe(
(value) => console.log(value)
);
您的代码不起作用的原因似乎是具有相同属性和值的对象在 JavaScript 中不被视为相等,因此 distinctUntilChanged
不起作用,因为
{prop: "value"} === {prop: "value"}
是 false
.
有一个简单的解决方案。不推荐用于长列表等,因为它在负载下表现不佳,但如果只是路由更改,那不会很快更改很多次。
this.activatedRoute.queryParams
.map((value) => {
// Your existing code or
const {page, ...otherProps} = value;
return otherProps;
})
// You tell it what to use as comparison
.distinctUntilChanged((oldProps, newProps) =>
JSON.stringify(oldProps) === JSON.stringify(newProps)
)
// Not sure you still need this
.skip(1)
.subscribe(
(value) => console.log(value)
);
您可以在 Object comparison in JavaScript 中阅读更多比较对象的方法。
更新:
这个答案被否决了,因为据说 JSON.stringify()
有时会以不同的顺序提供属性。
JSON.stringify()
的细节并不是真正答案的核心,这就是为什么我链接到另一个专注于对象比较的 SO 答案,但是,简单的谷歌搜索显示了另一个你可以使用的答案:
sort object properties and JSON.stringify
为了跟随答案,您更改此位:
.distinctUntilChanged((oldProps, newProps) =>
JSON.stringify(oldProps) === JSON.stringify(newProps)
)
变成类似这样的东西:
.distinctUntilChanged((oldProps, newProps) => {
// You can put this at the beginning of the file
// It doesn't need to live inside the RxJS operator
const createComparisonString =
(obj) => JSON.stringify(obj, Object.keys(obj).sort());
return createComparisonString(oldProps) === createComparisonString(newProps);
})
但是,JSON.stringify
并不是比较对象的唯一方法。如果您愿意,请参阅上面引用的答案以获取其他选项的示例。再次 Object comparison in JavaScript.