2015-09-20 12 views
7

Attualmente sto cercando di osservare eventuali modifiche a un determinato oggetto inclusi tutti gli elementi.Rxjs durante l'osservazione degli aggiornamenti degli oggetti e delle modifiche

Il seguente codice generato solo quando un oggetto [x] è aggiornamenti, ma oggetto non aggiornare se singolarmente [x] elementi s 'come oggetto [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> 

Questo codice viene eseguito e spara correttamente.

tuttavia. se preferisco questo

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

Quindi non succede nulla.

EDIT

Un modo migliore per frase questo, come posso osservare i cambiamenti da un array di oggetti?

+1

iniziare Probabilmente con l'utilizzo di 'ofArrayChanges' invece. – paulpdaniels

risposta

5

se desideri solo i cambiamenti degli oggetti nidificati:

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

Se si desidera anche cambiamenti come a[0] = a[1]:

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

Il flatMap o selectMany (sono la stessa funzione) vi permetterà di itera su un valore ed esegue una funzione che restituisce un Osservabile. I valori di tutti questi oggetti osservabili vengono "appiattiti" su un nuovo flusso che viene restituito.

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

+0

per farlo funzionare Ho avuto bisogno di cambiare rx in Rx e aggiungere la funzione mappa alla fine dell'unione. Freddo! – Antonio

+12

'rx.Observable.ofObjectChanges' sottratto. – serkan

+1

Sì, vedendo questo metodo come un valore deprecato, mi piacerebbe davvero vedere come osservare le modifiche dell'oggetto in RxJS 5 ... –

0

Forse qualcosa di simile dalla fusione di due osservabili (una per la matrice e l'altro osservando gli elementi dell'array):

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 

Grazie alla @electrichead qui non stiamo utilizzando concatMap perché le fonti che abbiamo fatto da ofObjectChanges e ofArrayChanges mai completato.

0

Ecco un esempio di lavoro di Rx.Observable.ofNestedObjectChanges semplice implementazione, è possibile ottenere l'essenza di esso e mettere in atto si possiede.

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

Controllato in Safari e Chrome. Lo snippet fornito dal link sembra essere rotto. – akaRem