Как я могу получить, какой объект изменился в BehaviourSubject в Rx Js? - PullRequest
0 голосов
/ 26 марта 2020

Я слушаю наблюдаемый ан после первого излучения со всеми объектами, я бы хотел получить только объект, который изменился. Поэтому, если у меня есть:

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

и затем изменение имени, я получу только объект, который изменился. Поэтому, если объект становится:

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

, я получаю только

[{name: 'Jean Mark'}]

Ответы [ 2 ]

1 голос
/ 26 марта 2020

Ваш Observable испускает массивы, и вы хотите знать разницу между текущим израсходованным массивом и предыдущим. Отслеживание изменений состояния массива больше связано с тем, как сравнивать массивы или объекты, чем с Observables.

Если вы хотите отслеживать изменения в Observable, то все сводится к сравнению предыдущего с текущим значением. Логика c, которую вы хотите использовать здесь, зависит от вас. например, вам нужно подумать о том, как отличить guish между «измененным» значением и вновь «добавленным» значением в массиве?

Вы можете сравнить текущее значение cv с предыдущим pv в Observable с использованием pairwise. Вот как это может выглядеть.

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) => prev
  ? { 
      added: curr.filter(o1 => !prev.some(o2 => objectsEqual(o1, o2))),
      removed: prev.filter(o1 => !curr.some(o2 => objectsEqual(o1, o2)))
    } 
  : { added: curr, removed: [] }

source.pipe(
  startWith(undefined), // 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-anzyhm

0 голосов
/ 26 марта 2020

Вы можете наблюдать массив (значение индекса / добавлять / удалять) с прокси javascript, но он не отслеживает изменения объекта в массиве.

const handler = {
set: function(target, property, value, receiver){
   console.log('setting ' + property + ' for ' + target + ' with value ' + value);
   target[property] = value;
   return true;

  }
}


const arr=[{name: 'Mark'},{name: 'Joe'}];
const proxy = new Proxy(arr, handler);
// will log
proxy[0]="hello"
// won't log
proxy[0].name="ben"

если вы также хотите следить за изменением объекта, вам нужно либо использовать прокси для каждого добавленного объекта, либо создать свой объект для добавления с помощью Object.defineProperty () и добавьте свой установщик

Существует также существующая библиотека, которая отслеживает изменения как объектов, так и массивов, и она также использует proxy https://github.com/ElliotNB/observable-slim/

...