2012-12-04 15 views
6

Nel mio modello ho una proprietà che viene caricata in modo asincrono. Voglio che generi un'altra proprietà del modello dopo che è stata caricata.Come creare un abbonamento osservabile a eliminazione diretta che si attiva solo una volta?

Stavo pensando all'abbonamento che potrebbe sparare dopo le modifiche alla 1a proprietà, genera la 2a proprietà e poi viene eliminata - Non so come posso disporre dell'abbonamento da dentro se stesso.

C'è un modo per far scattare un evento di una volta dopo che le proprietà osservabili sono cambiate?

risposta

0

Si potrebbe scrivere un estensore di sopprimere tutti, ma la prima cottura:

ko.extenders.fireOnce= function(target) { 
    var fired=false; 
    var result = ko.computed({ 
     read: target, 
     write: function(newValue) { 
      var current = target(); 
      if (newValue!== current && !fired) { 
       fired=true; 
       target(newValue); 
      } 
     } 
    }); 
    result(target()); 
    return result; 
}; 

quindi utilizzarlo come segue:

var myObservable = ko.Observable(blah).extend({fireOnce:null}); 
+0

Questo extender deve essere denominato 'changeOnce', perché sarà ignorato tutte le variazioni di valore ad eccezione di prima. – blazkovicz

+0

@blazkovicz ... e questa è la tua base per un downvote? – spender

+2

sì, perché la domanda era sull'abbonamento, che si accende una volta e tu hai suggerito un osservabile che _ cambia una volta_. Queste sono due cose molto diverse. – blazkovicz

21

di disporre di sottoscrizione da dentro sé basta creare riferimento ad essa:

var subscription = yourObservable.subscribe(function (newValue) { 
    ... 
    subsription.dispose(); 
}); 

Se non si desidera scrivere questo codice ogni volta, è possibile estendere l'osservazion le con nuovo metodo:

ko.subscribable.fn.subscribeOnce = function (handler, owner, eventName) { 
    var subscription = this.subscribe(function (newValue) { 
     subscription.dispose(); 
     handler(newValue); 
    }, owner, eventName); 
    return subscription; 
}; 

... 

// usage 
var subscription = yourObservable.subsribeOnce(yourHandler); 

E non dimenticare di disporre l'abbonamento per lo smaltimento dei componenti nel caso in cui non è stato licenziato.

0

Abbiamo finito con una soluzione come questa ...

const subscription = observable.subscribe(() => { 
    subscription.dispose(); 
    doStuff(settings); 
}); 

speranza che qualcuno può usarlo.

0

Elaborazione su @blazkovicz risposta, subscribeOnce potrebbe restituire un Promise eventualmente risolto con il nuovo valore. Aperto a suggerimenti su come esporre l'oggetto subscription ;-)

ko.subscribable.fn.subscribeOnce = function (handler, owner, eventName) { 
    var subscribable = this; 
    var subscription; 
    return new Promise(function(resolve) { 
     subscription = subscribable.subscribe(resolve, owner, eventName); 
    }).then(function(newValue) { 
     subscription.dispose(); 
     handler && handler(newValue); 
     return newValue; 
    }); 
}; 

// usage 
yourObservable.subscribeOnce().then(function(newValue) { 
    ... 
}); 
Problemi correlati