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ć? 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ść.
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.
- Using
BehaviorSubject
: But actually subscribing to it . Kiedy po raz pierwszy subskrybujeszBehaviorSubject
, synchronicznie wyśle ona poprzednią wartość, którą otrzymał lub została zainicjowana. - użycie
ReplaySubject(N)
: spowoduje to buforowanie wartościN
i ponowne przekazanie ich nowym subskrybentom. -
A.withLatestFrom(B)
: Użyj tego operatora, aby uzyskać najnowszą wartość z observableB
, gdy observableA
emituje. Poda obie wartości w tablicy[a, b]
. -
A.combineLatest(B)
: użyj tego operatora, aby uzyskać najnowsze wartości zA
iB
za każdym razem, gdy emituje sięA
lubB
. Poda obie wartości w tablicy. -
shareReplay()
: tworzy obserwowalny multicast poprzezReplaySubject
, ale pozwala na ponowne spróbowanie obserwowalnego po błędzie. (W zasadzie daje Ci tę obietnicę-y buforowanie zachowanie). -
publishReplay()
,publishBehavior(initialValue)
,multicast(subject: BehaviorSubject | ReplaySubject)
, etc: inni operatorzy, którzy wykorzystująBehaviorSubject
iReplaySubject
. 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.
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
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:)
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;
}
);
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