How to watch object changes with rxjs 5

后端 未结 3 2214
孤街浪徒
孤街浪徒 2021-02-08 23:41

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 si

相关标签:
3条回答
  • 2021-02-08 23:53

    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>

    0 讨论(0)
  • 2021-02-08 23:58

    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 }
    
    0 讨论(0)
  • 2021-02-09 00:07

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

    0 讨论(0)
提交回复
热议问题