2012-12-04 23 views
6

W moim modelu mam właściwość, która jest ładowana asynchronicznie. Chcę, aby wygenerował inną właściwość modelu po załadowaniu.Jak utworzyć subkonkurencyjną subskrypcję, która uruchamia się tylko raz?

Myślałem o subskrypcji, która może wystrzelić po pierwszej zmianie własności, generuje drugą nieruchomość, a następnie się pozbyć - nie wiem, w jaki sposób mogę wykupić subskrypcję od wewnątrz.

Czy istnieje sposób na wystrzelenie jednorazowego zdarzenia po zaobserwowaniu zmian właściwości?

Odpowiedz

0

Mogłeś napisać przedłużacz stłumić wszystko ale pierwszy wypalania:

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; 
}; 

następnie używać go w sposób następujący:

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

Ten przedłużacz powinien być nazwany 'changeOnce', ponieważ wszelkie zmiany wartości za wyjątkiem pierwszej będą ignorowane. – blazkovicz

+0

@blazkovicz ... i to jest twoja podstawa do przegłosowania? – spender

+2

tak, ponieważ pytanie dotyczyło subskrypcji, raz się rozpalało, a Ty zasugerowałeś obserwację, że _changes once_. To są dwie bardzo różne rzeczy. – blazkovicz

21

Aby wyrzucać subskrypcji od wewnątrz siebie wystarczy utworzyć odniesienie do niej:

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

Jeśli nie chcesz pisać tego kodu za każdym razem, możesz rozszerzyć observab le z nową metodą:

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); 

I nie zapomnij złożyć subskrypcji na składowanie składników w przypadku, gdy nie został zwolniony.

0

Skończyło się z takiego rozwiązania ...

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

nadzieję, że ktoś może go używać.

0

Opracowanie na @blazkovicz odpowiedź, subscribeOnce może zwrócić Promise ostatecznie rozwiązany z nową wartością. Otwarty na sugestie, w jaki sposób wystawiać przedmiotów 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) { 
    ... 
}); 
Powiązane problemy