为什么没有RxJS运算符从流中删除特定项?

时间:2018-01-08 20:32:56

标签: angular rxjs reactive

我难以置信地试图从可观察的流中删除属性。我有一个observable,它在url中发出查询参数对象(angular' s ActivatedRoute.queryParams)。我试图删除密钥和密钥。来自发射值的值并调用distinctUntilChanged(),以便它们的更改不会触发我的观察者。

pluck()允许您只允许流中的一个参数,filter()允许您过滤整个流,skip()运算符允许您跳过整个流的排放,{{1限制排放量。虽然要做throttle()的相反 - 你想要允许除了一个流的所有值之外的所有值都通过 - 不存在。你可以获得最接近它的是map(),它创建一个新对象,删除属性,然后返回那个新对象,但这种情况最多,而且往往不起作用。

我已经尝试为所有查询参数属性创建单独的订阅,除了我试图忽略的那个。我想有必要有一个更好的方法来解决这个问题,是否有一些神奇的算子让我失踪或解决?当pluck()之类的东西存在时,为什么反应库中缺少这样一个明显的运算符?

编辑:

代码:

pluck()

1 个答案:

答案 0 :(得分:4)

您的代码无法正常工作的原因似乎是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