How to watch object changes with rxjs 5

只谈情不闲聊 提交于 2019-12-04 19:50:56

问题


I would like to watch over an object, so all the subscribers will be informed for any changes of it.

I saw it already been asked before, yet the answer is irrelevant since RXjs verion 5 do not include the ofObjectChanges in it's API anymore.

I've looked at some "hacks" like creating an observer which return a function:

let myObservable =  new Observable((observer) => {
  return (data) => {
    observer.next(data)
  }
}) 
//...
myObservable.subscribe()('someData')

However, I'm sure there is more elegant way of doing it. Any Ideas?


回答1:


You need to use Behavior Subject . https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md




回答2:


The ES6 way of observing an object is with Proxies. You create a Proxy that wraps the original object and do your work on it. You can use it to create something similar to Observable.ofObjectChanges. Here a partial implementation (only set. You'd need to implement the other traps):

Observable.ofProxyChanges = (target) => {
  let subject = new Subject
  let proxy = new Proxy(target, {
    set(target, key, val) {
      let oldValue = target[key]
      target[key] = val
      subject.next({
        type: oldValue === undefined ? "add" : "change",
        object: target,
        name: key,
        oldValue: oldValue
      })
    }
  })
  return [proxy, subject.asObservable()]
}

let [obj, objChange$] = Observable.ofProxyChanges({})
objChange$.subscribe(console.log)

obj.bar = 1 // logs { type: "add", name: "bar", object: { bar: 1 } }
obj.foo = 2 // logs { type: "add", name: "foo", object: { bar: 1, foo: 2 } }
obj.foo = 3 // logs { type: "change", name: "foo", object: { bar: 1, foo: 3 }, oldValue: 2 }



回答3:


I would suggest using something similar to redux approach, when changes to the object can be made in predefined way:

function factory(reducerByType, initialState) {
  const action$ = new Rx.Subject();
  const state$ = action$
    .startWith(initialState)
    .scan((state, action) => {
      if (reducerByType.hasOwnProperty(action.type)) {
        return reducerByType[action.type](state, action);
      }
      
      return state;
    })
    .distinctUntilChanged();
  
  
  return {
    action$,
    state$,
    dispatch: action => action$.next(action)
  }
}

const {state$, dispatch} = factory({
  ADD: (state, action) =>  state + action.number,
  SUBTRACT: (state, action) =>  state - action.number,
}, 0);

state$.subscribe(val => console.log(val));

dispatch({
  type: 'ADD',
  number: 10,
});

dispatch({
  type: 'SUBTRACT',
  number: 15,
});

dispatch({
  type: 'SUBTRACT',
  number: 0,
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.js"></script>


来源:https://stackoverflow.com/questions/44369387/how-to-watch-object-changes-with-rxjs-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!