首页 > 解决方案 > 如何在 RxJs 的 BehaviourSubject 中获取更改的对象?

问题描述

在第一次发射所有对象后,我正在听一个可观察的,我只想得到改变的对象。所以如果我有:

[{name: 'Mark'},{name: 'Joe'}]

然后更改名称,我只得到更改的对象。因此,如果对象变为:

[{name: 'Jean Mark'},{name: 'Joe'}]

我只得到

[{name: 'Jean Mark'}]

标签: rxjsobservable

解决方案


您的 Observable 发出数组,您想知道当前发出的数组与前一个数组之间的区别。跟踪数组状态变化更多地与如何比较数组或对象有关,而不是与 Observables 相关。

如果你想跟踪 Observable 中的变化,它实际上归结为将以前的值与当前值进行比较。您想在此处使用的逻辑取决于您。例如,您必须考虑如何区分数组中的“修改”值和新“添加”值?

查看这些问题以帮助您入门:

您可以使用 将当前值与Observable 中cv的前一个值进行比较。这是它的外观。pvpairwise

const source = of(
  [{ name: "Mark", p: 2 }, { name: "Joe", p: 3 }],
  [{ name: "Jean Mark", p: 2 }, { name: "Joe", p: 3 }],
  [{ name: "Jean Mark", p: 1 }, { name: "Joe", p: 3 }, { name: 'Alice' }],
  [{ name: "Jean Mark", p: 1 }, { name: "Joe", p: 3 }],
  [{ name: "Jean Mark", p: 1 }, { name: "Joe", p: 4 }],
  [{ name: "Jean Mark", p: 1 }, { name: "Joe", p: 4 }]
);

// compare two objects
const objectsEqual = (o1, o2) =>
  typeof o1 === "object" && Object.keys(o1).length > 0
    ? Object.keys(o1).length === Object.keys(o2).length &&
      Object.keys(o1).every(p => objectsEqual(o1[p], o2[p]))
    : o1 === o2;

// compare two arrays 
// REPLACE this function with YOUR OWN LOGIC to get your desired output !!!
const difference = (prev, curr) => ({ 
  added: curr.filter(o1 => !prev.some(o2 => objectsEqual(o1, o2))),
  removed: prev.filter(o1 => !curr.some(o2 => objectsEqual(o1, o2)))
})

source.pipe(
  startWith([]), // used so that pairwise emits the first value immediately
  pairwise(), // emit previous and current value
  map(([pv, cv]) => difference(pv, cv)) // map to difference between pv and cv
).subscribe(console.log);

https://stackblitz.com/edit/rxjs-m9ngjy?file=index.ts


推荐阅读