Inspiriert durch das Beispiel bei angular.io (Eltern und Kinder kommunizieren über einen Dienst) Ich implementierte ein Observer/beobachtbares Muster, um meine Navigationskomponente zu benachrichtigen, ob der Benutzer authentifiziert ist. Das Problem ist, dass die Navigationskomponente nur eine Benachrichtigung erhält, wenn der Benutzer sich abmeldet.Beobachter erhält nur Wert von einem nächsten Anruf
Mein Authentifizierungsdienst wie folgt aussieht:
export class AuthenticationService {
private isAuthenticatedSource = new Subject<boolean>();
isAuthenticated$ = this.isAuthenticatedSource.asObservable();
constructor(private http : AuthHttp) {}
login(email: string, password: string) {
...
this.isAuthenticatedSource.next(true);
...
}
logout() {
...
this.isAuthenticatedSource.next(false);
...
}
}
ich dafür gesorgt habe, dass beiden Anrufe (Login- und Logout) gemacht werden und keine Fehler geworfen werden. Meine Navigationskomponente wie folgt aussieht:
export class NavigationComponent implements OnDestroy, OnInit {
private subscription: Subscription;
isAuthenticated: boolean;
constructor(private authService: AuthenticationService,
private router: Router) {
this.isAuthenticated = authService.isAuthenticated();
}
logout(event) {
event.preventDefault();
this.authService.logout();
this.router.navigate(["Authentication", "Login"]);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngOnInit() {
this.subscription = this.authService.isAuthenticated$.subscribe(
value => console.log("updated to:", value)
);
}
}
Die Konsole sollte lügt „Aktualisiert: true“, wenn Sie sich anmelden und „Aktualisiert: false“ beim Abmelden. Das Problem ist, dass beim Abmelden nur eine Nachricht angezeigt wird. Offensichtlich erhält der Beobachter beim Einloggen nicht den Wert (true). Hoffentlich können Sie erklären, warum dies geschieht.
aktualisieren
Der Anruf jetzt unten enthalten ist, um sich einzuloggen. Es wird von meinem LoginComponent
aufgerufen, wenn ein Benutzer ein (Login) Formular einreicht. LoginComponent
wie folgt aussieht:
export class LoginComponent {
public email : string;
public password : string;
public errors : any;
public next : any;
constructor(private authService : AuthenticationService,
private router : Router,
private params : RouteParams) {
// default to navigate to dashboard on successfull login
let next = this.params.get("next") || "/Dashboard";
this.next = [next];
}
login(event) {
event.preventDefault();
this.authService.login(this.email, this.password)
.subscribe(
data => this.router.navigate(this.next),
errors => this.errors = errors);
}
}
Die entsprechende Vorlage einen einzigen Anruf hat sich einloggen: <form (submit)="login($event)">
. Login wird nicht an anderen Stellen in der Anwendung aufgerufen.
Sie können bereits im Konstruktor subskribieren, ohne auf 'ngOnInit() 'warten zu müssen, wenn der Code nicht davon abhängt, dass Eingaben aktualisiert werden. Vielleicht wurde das Ereignis bereits gesendet, bevor die 'NavigationComponent' abonniert wurde. Ich denke, dass Sie ein 'BehaviorSubject' benötigen, um den letzten Wert sofort nach dem Abonnieren zu erhalten. –
Ich sehe den Aufruf von 'login' in Ihrem Code nicht - Sind Sie sicher, dass Sie das _after_ anrufen, nachdem Sie den Betreff abonniert haben? Ein Subjekt sendet nur Ereignisse nach Subskription an Subskribenten - möglicherweise möchten Sie eine andere Art von Subjekt, vielleicht 'BehaviorSubject' – tddmonkey
Danke für die Rückmeldung. Versuchte BehaviorSubject und es hat nichts geändert. Ich werde auch den Subskriptionsaufruf an den Konstruktor verschieben, aber die Situation ist immer noch dieselbe. @tddmonkey Ja bin ich mir sicher. Login wird aufgerufen, wenn ein Benutzer auf eine Schaltfläche klickt - lange nachdem NavigationComponent den Betreff abonniert hat. – ThaBird