2015-04-13 10 views
7

Ich habe Schwierigkeiten, den "Rx" Weg zu finden, einen Ladeindikator für einen AJAX-Stream anzuzeigen.RxJS - Ladeindikator

$scope.$createObservableFunction("load") 
     .take(1) 
     .do(function(){ 
      $scope.loading = true; 
     }) 
     .flatMap(contentService.AJAX_THINGY_AS_OBSERVABLE) 
     .delay(300) 
     .subscribe(function(content){ 
      console.log("content",content); 
     },function(error){ 
      $scope.error = error 
     },function() { 
      $scope.loading = false; 
     }); 

Soweit ich es verstehe sollte ich .do() für Nebenwirkungen verwenden, die ich loading nehme Einstellung ist, aber es fühlt sich nicht wie die richtige Art und Weise, Dinge zu tun.

Kann jemand ein saubereres/besseres/richtiges Beispiel dafür zur Verfügung stellen?

Danke!

UPDATE 1

I entschieden, dies in 2 Ströme aufgeteilt; requestSource und responseSource.

var loadRequestSource = $scope.$createObservableFunction("load") 
    .share(); 

var loadResponseSource = loadRequestSource 
    .flatMap(contentService.AJAX_THINGY_AS_OBSERVABLE) 
    .throttle(1000) 
    .share(); 

haben dann 2 separate Abonnenten:

loadRequestSource.subscribe(function() { 
    $scope.loading = true; 
}); 

loadResponseSource.subscribe(function (response) { 
    /* enter logic */ 
    $scope.loading = false; 
    $scope.$digest(); 
}, function (err) { 
    $scope.error = err; 
    $scope.loading = false; 
    $scope.$digest(); 
}); 

ich diesen Ansatz bin gefallen, da sie die Rolle der abonnierten genau hält. Der Antwortteilnehmer muss sich nicht darum kümmern, loading auf true zu setzen. Es ist nur wichtig, es auf false einzustellen.

+0

Mangel an '$ scope $ Digest()' ist nicht ein Problem in diesem Fall ? –

+0

Ich fand später heraus, dass ich es brauchte, ja. – MaxWillmo

+0

Wie auch immer, Sie haben nach dem Konzept gefragt, was "der Weg" ist, es zu tun. Um ehrlich zu sein, sehe ich keinen geeigneteren Ansatz: P Ich würde es testbar machen, z. Logik vom Code entkoppeln, der Flags auf $ scope setzt. Aber außerdem weiß ich nicht, was du besser machen kannst. –

Antwort

1

ich die Anfrage/Antwort wie die Umwandlung eines einzelnen Strom Ströme in, die den aktuellen Zustand Ihrer Lade Eigenschaft darstellt.

const startLoading$ = loadRequestSource.map(() => true); 
const stopLoading$ = loadResponseSource.map(() => false); 
const loadingState$ = Rx.Observable.merge(startLoading$, stopLoading$); 

// Finally, subscribe to the loadingState$ observable 
loadingState$.subscribe(state => { 
    $scope.$applyAsync(() => $scope.loading = state); 
});