2017-06-05 20 views
3

オブジェクトを監視したいので、すべてのサブスクライバにその変更が通知されます。rxjsでオブジェクトの変更を監視する方法5

私はそれがすでにasked before、 れていRXjsのverion 5はもうそれのAPIにofObjectChangesが含まれていないので、答えは無関係です見ました。

私は関数を返しオブザーバを作成するようないくつかの「ハック」を見てきました:

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 }