2017-06-05 359 views
3

我想监视一个对象,因此所有订阅者都将被通知其任何更改。如何使用rxjs监视对象变化5

我看到它已经asked before, 但因为RXjs优化版本5不包括ofObjectChanges在它的API了,答案是不相关的。

我已经看了一些“黑客”般创造它返回一个函数的观察员:

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

不过,我敢肯定有这样做的更优雅的方式。 任何想法?

+0

我很感兴趣,接受这个问题的答案 – Marin

+0

有没有尝试过,但我相信@Skeptor答案在我的情况下会很有用。 –

回答

2

我会建议使用类似于Redux的方法什么的,当对象的变化可以在预定的方式进行:

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>

3

ES6观察物体的方式是用Proxies。您创建一个包装原始对象的代理服务器,并在其上进行工作。你可以用它来创建类似于Observable.ofObjectChanges的东西。这里的部分实现(仅set你需要执行其他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 }