Jak uzyskać aktualną wartość Rxjs Subject lub Observable?

Mam serwis Angular 2:

import {Storage} from './storage';
import {Injectable} from 'angular2/core';
import {Subject}    from 'rxjs/Subject';

@Injectable()
export class SessionStorage extends Storage {
  private _isLoggedInSource = new Subject<boolean>();
  isLoggedIn = this._isLoggedInSource.asObservable();
  constructor() {
    super('session');
  }
  setIsLoggedIn(value: boolean) {
    this.setItem('_isLoggedIn', value, () => {
      this._isLoggedInSource.next(value);
    });
  }
}
Wszystko działa świetnie. Ale mam inny komponent, który nie musi subskrybować, po prostu musi uzyskać aktualną wartość isLoggedIn w pewnym momencie. Jak mogę to zrobić?
Author: Baconbeastnz, 2016-05-07

5 answers

A Subject LUB Observable nie ma bieżącej wartości. Gdy wartość jest emitowana, jest przekazywana subskrybentom i Observable jest z nią wykonywana.

Jeśli chcesz mieć bieżącą wartość, użyj BehaviorSubject, która jest zaprojektowana dokładnie do tego celu. BehaviorSubject zachowuje ostatnią emitowaną wartość i wysyła ją natychmiast do nowych subskrybentów.

Posiada również metodę getValue(), aby uzyskać bieżącą wartość.

 173
Author: Günter Zöchbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-07 14:56:26

Jedynym sposobem powinno być uzyskanie wartości" z " obserwowalne / Temat jest z Subskrybuj!

Jeśli używasz getValue() robisz coś imperatywnego w paradygmacie deklaratywnym. Jest tam jako właz ratunkowy, ale 99,9% czasu nie powinno się używać getValue(). jest kilka interesujących rzeczy, które getValue() zrobią: spowoduje to wyświetlenie błędu, jeśli Temat został anulowany, uniemożliwi uzyskanie wartości, jeśli Temat jest martwy, ponieważ jest błąd itp. Ale, znowu, jest tam jako właz ratunkowy w rzadkich okolicznościach.

Istnieje kilka sposobów uzyskania najnowszej wartości z obiektu lub Obserwowalnej w sposób "Rx-y":]}
  1. Using BehaviorSubject: But actually subscribing to it . Kiedy po raz pierwszy subskrybujesz BehaviorSubject, synchronicznie wyśle ona poprzednią wartość, którą otrzymał lub została zainicjowana.
  2. użycie ReplaySubject(N): spowoduje to buforowanie wartości N i ponowne przekazanie ich nowym subskrybentom.
  3. A.withLatestFrom(B): Użyj tego operatora, aby uzyskać najnowszą wartość z observable B, gdy observable A emituje. Poda obie wartości w tablicy [a, b].
  4. A.combineLatest(B): użyj tego operatora, aby uzyskać najnowsze wartości z A i B za każdym razem, gdy emituje się A lub B. Poda obie wartości w tablicy.
  5. shareReplay(): tworzy obserwowalny multicast poprzez ReplaySubject , ale pozwala na ponowne spróbowanie obserwowalnego po błędzie. (W zasadzie daje Ci tę obietnicę-y buforowanie zachowanie).
  6. publishReplay(), publishBehavior(initialValue), multicast(subject: BehaviorSubject | ReplaySubject), etc: inni operatorzy, którzy wykorzystują BehaviorSubject i ReplaySubject. Różne smaki tego samego, one w zasadzie multicast źródła obserwowalne przez lejek wszystkie powiadomienia przez temat. Musisz zadzwonić connect(), aby zapisać się do źródła z tematem.
 78
Author: Ben Lesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-26 17:17:46

Miałem podobną sytuację, w której późni subskrybenci subskrybują temat po przybyciu jego wartości.

Znalazłem ReplaySubject który jest podobny do BehaviorSubject działa jak urok w tym przypadku. A oto link do lepszego wyjaśnienia: http://reactivex.io/rxjs/manual/overview.html#replaysubject

 4
Author: Kfir Erez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 10:42:28

Napotkałem ten sam problem w komponentach potomnych, gdzie początkowo musiałby mieć aktualną wartość tematu, a następnie subskrybować temat, aby słuchać zmian. Po prostu utrzymuję aktualną wartość w usłudze, aby była dostępna dla komponentów, aby uzyskać dostęp, np.:

import {Storage} from './storage';
import {Injectable} from 'angular2/core';
import {Subject}    from 'rxjs/Subject';

@Injectable()
export class SessionStorage extends Storage {

  isLoggedIn: boolean;

  private _isLoggedInSource = new Subject<boolean>();
  isLoggedIn = this._isLoggedInSource.asObservable();
  constructor() {
    super('session');
    this.currIsLoggedIn = false;
  }
  setIsLoggedIn(value: boolean) {
    this.setItem('_isLoggedIn', value, () => {
      this._isLoggedInSource.next(value);
    });
    this.isLoggedIn = value;
  }
}

Komponent, który potrzebuje bieżącej wartości, może po prostu uzyskać do niego dostęp z usługi, tj.:

sessionStorage.isLoggedIn

Nie wiem czy to dobra praktyka:)

 2
Author: Molp Burnbright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-25 06:01:47

Można zapisać ostatnią emitowaną wartość oddzielnie od Obserwowalnej. Następnie przeczytaj go w razie potrzeby.

let lastValue: number;

const subscription = new Service().start();
subscription
    .subscribe((data) => {
        lastValue = data;
    }
);
 -3
Author: Slawa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 11:36:44