如何使用 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));

当上面的代码运行时,我正确地获得更新,告诉我窗口对象中的某些内容何时更改,但是我不知道如何确定哪个属性是更改的属性。

我将如何修改它,以便我可以看到在第一次更改中,leftPanelWidth300更改为250,而在下一次更改中,backgroundColor0xffffff更改为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>

最新更新