2015-09-20 15 views
7

現在、オブジェクトのすべての要素を含む特定のオブジェクトの変更を監視しようとしています。このようなオブジェクトとしてオブジェクトの更新と変更を観測しているRxjs

次のコードのみ起動オブジェクト[x]は、個別のオブジェクトを更新する場合の更新ではなく、[X]の要素[X] [Y]

<script> 
    var elem = document.getElementById("test1"); 

var log = function(x) { 
    elem.innerHTML += x + "<br/><br/><br/>"; 
}; 

var a = [{a:1,b:2}, 
     {a:2,b:5} 
     ]; 


var source = Rx.Observable 
.ofObjectChanges(a) 
.map(function(x) { 
    return JSON.stringify(x); 
}); 


var subscription = source.subscribe(
    function (x) {log(x);}, 
    function (err) {log(err);}, 
    function() {log('Completed');} 
); 

a[0] = a[1]; 
</script> 

このコードが実行され、正しく発火する。

ただし、代わりにこの場合

a[0]['a'] = 3; 

何も起こりません。

EDIT

フレーズこれまでより良い方法、どのように私は、オブジェクトの配列からの変化を観察することができますか?

+1

おそらく代わりに 'ofArrayChanges'使用して開始します。 – paulpdaniels

答えて

5

は、あなただけのネストされたオブジェクトの変更をしたい場合Observableを返す関数を実行して値を反復処理します。これらのオブザーバブルからの値は、返される新しいストリームに「フラット化」されます。ここで

http://reactivex.io/documentation/operators/flatmap.html

+0

私はrxをRxに変更し、マージの終わりにマップ関数を追加する必要がありました。クール! – Antonio

+12

'rx.Observable.ofObjectChanges'がデリケートされました。 – serkan

+1

このメソッドが償却されているのを見て、私は本当にRxJS 5のオブジェクトの変更を観察する方法を見てみたいです... –

0

おそらく2つの観測(配列の要素を観察し、アレイおよびその他のための1)をマージすることによって、このような何か:

var a = [ 
    {a:1,b:2}, 
    {a:2,b:5} 
]; 


var source1 = Rx.Observable.ofArrayChanges(a).map(function(x) { 
    return JSON.stringify(x); 
}); 

var source2 = Rx.Observable 
.fromArray(a.map(function(o, i) { return [o, i]; })) 
.flatMap(function(oi) { 
    return Rx.Observable.ofObjectChanges(oi[0]) 
    .map(function(x) { 
    var y = { 
     type: x.type, 
     object: x.object, 
     name: x.name, 
     oldValue: x.oldValue, 
     arrayIndex: oi[1] // pass the index of the member that changed 
    }; 
    return JSON.stringify(y); 
    }); 
}) 

source = source1.merge(source2) 

var subscription = source.subscribe(
    function (x) {log(x);}, 
    function (err) {log(err);}, 
    function() {log('Completed');} 
); 


a[0] = a[1] 
a[1]['b'] = 7 

おかげで、我々がいることを情報源のでconcatMapを使用していないここに@electricheadします我々はofObjectChangesofArrayChangesによって決して完了しませんでした。にあなたをできるようになります

var source = rx.Observable.merge(
    rx.Observable.ofArrayChanges(a), 
    rx.Observable.from(a).flatMap(function(item) { 
    return rx.Observable.ofObjectChanges(item); 
    }) 
); 

flatMapまたはselectMany(彼らは同じ機能):

var source = rx.Observable.from(a).flatMap(function(item) { 
    return rx.Observable.ofObjectChanges(item); 
}); 

あなたもa[0] = a[1]のような変更をしたい場合:

0

がRx.Observable.ofNestedObjectChanges単純な実装の作業例ですが、あなたはそれの要点を取得し、あなたが所有して実装することができます。

http://jsbin.com/wekote/edit?js,console

 Rx.Observable.ofNestedObjectChanges = function(obj) { 
      if (obj == null) { throw new TypeError('object must not be null or undefined.'); } 
      if (typeof Object.observe !== 'function' && typeof Object.unobserve !== 'function') { throw new TypeError('Object.observe is not supported on your platform') } 
      return new Rx.AnonymousObservable(function(observer) { 
       function observerFn(changes) { 
        for(var i = 0, len = changes.length; i < len; i++) { 
         observer.onNext(changes[i]); 
        } 
       } 
       Object.observe(obj, observerFn); 
       //Recursive observers hooks - same observerFn 
       traverseObjectTree(obj, observerFn); 

       function traverseObjectTree(element, observerFn){ 
        for(var i=0;i<Object.keys(element).length;i++){ 
         var myObj = element[Object.keys(element)[i]]; 
         if(typeof myObj === "object"){ 
          Object.observe(myObj, observerFn); 
          traverseObjectTree(myObj,observerFn); 
         } 
        } 
       } 

       return function() { 
        Object.unobserve(obj, observerFn); 
       }; 
      }); 
     }; 



     //Test 
     var json = { 
      element : { 
       name : "Yocto", 
       job : { 
        title: "Designer" 
       } 
      }, 
      element1: { 
       name : "Mokto" 
      } 
     }; 

     setTimeout(function(){ 
      json.element.job.title = "A Great Designer"; 
     },3000); 


     var source = Rx.Observable.ofNestedObjectChanges(json); 

     var subscription = source.subscribe(
      function (x) { 
       console.log(x); 
      }, 
      function (err) { 
       console.log('Error: %s', err); 
      }, 
      function() { 
       console.log('Completed'); 
      }); 

     json.element.name = "Candy Joe"; 
+0

SafariとChromeでチェックアウトしました。リンクで提供されるスニペットが壊れているようです。 – akaRem

関連する問題