如何用rxjs观察多个对象属性的变化?

How to observe multiple object property changes with rxjs?

我有一个对象,我想使用 rxjs 观察它的变化。该对象有多个属性,当它们中的任何一个发生变化时,我想知道哪个被改变了,它的新值是什么。我整理了以下代码的简化版本,但它没有按预期工作:http://jsbin.com/sidukulowi/1/edit?js,console

const store = Rx.Observable.create(function(observer) {
  let state = { userActions: {
    window: {
      leftPanelWidth: 300,
      backgroundColor: 0xffffff,
    }
  }};

  observer.next(state);

  state = { userActions: {
    window: {
      leftPanelWidth: 250,
      backgroundColor: 0xffffff,
    }
  }};

  observer.next(state);

  state = { userActions: {
    window: {
      leftPanelWidth: 250,
      backgroundColor: 0xff00ff,
    }
  }};

  observer.next(state);
});


const subscribe = store
  .map( state => state.userActions.window )
  .distinctUntilChanged( ( a, b ) => {
    return a.leftPanelWidth === b.leftPanelWidth && a.backgroundColor === b.backgroundColor
  })
  .subscribe(val => console.dir(val));

当上面的代码运行时,我正确地得到了更新,告诉我什么时候 window 对象发生了变化,但是我不知道如何确定哪个 属性 是那个改变了。

我该如何修改才能看到在第一个更改中,leftPanelWidth300 更改为 250,在下一个更改中backgroundColor 是从 0xffffff 变成了 0xff00ff 吗?

我才刚刚开始学习 RxJX Observable,。所以这可能不是最简单的解决方案。

但是您可以使用 pairwise 来检查之前和当前的值,而不是 distinctUntilChanged

例如

const store = Rx.Observable.create(function(observer) {
  let state = { userActions: {
    window: {
      leftPanelWidth: 300,
      backgroundColor: 0xffffff,
    }
  }};
  
  observer.next(state);
  
  state = { userActions: {
    window: {
      leftPanelWidth: 250,
      backgroundColor: 0xffffff,
    }
  }};
  
  observer.next(state);
  //lets add again to make sure it only when
  //changed..
  observer.next(state); 
  
  state = { userActions: {
    window: {
      leftPanelWidth: 250,
      backgroundColor: 0xff00ff,
    }
  }};
  
  observer.next(state);
  
});


const subscribe = store
  .map(a => a.userActions.window)
  .pairwise()
  .map(([a,b]) => 
    Object.entries(a)
      .filter(([k,v]) => b[k] !== v)
      .map(([k,v]) => ({
        property: k,
        old: a[k],
        new: b[k]
      }))
  )
  .filter(a => a.length)
  .subscribe(val => console.dir(val));

console.log( '--------------Done--------------' );
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.8/Rx.min.js"></script>