2016-09-09 5 views
2

Ich bin ziemlich neu zu angular2, aber ich habe versucht, eine Login-Komponente zu schreiben. Alles funktioniert gut, außer nach einer erfolgreichen Anmeldung Ich möchte den Benutzernamen und das Passwort in meinem Sitzungsdienst (wo ich den Benutzernamen und das Passwort speichern, um grundlegende Auth-Header erstellen). Leider this._session.loggedIn wird nie eingestellt. Jemand eine Idee warum?Angular2 Set-Variable auf abonnieren funktioniert nicht

export class LoginComponent { 

    public email = ''; 
    public password = ''; 

    constructor(
     private _router: Router, 
     private _auth: AuthenticationService, 
     private _session: SessionService) { 
    } 

    login() { 
     this._auth.login(this.email, this.password) 
      .subscribe(
       data => { 
        this._session.currentProfile = data; 
        this._session.loggedIn = true; 
        this._router.navigate(['Home']); 
       }, 
       err => {} 
      ); 
    } 
} 

AuthenticationService:

login(email, password){ 
     return this._http.get('/profile') 
      .map(res => res.json()); 
} 
+0

Was ist die login() Methode? Wann sollte es aufgerufen werden? Wenn Sie abonnieren, wird ein Ereignis nicht dynamisch gesendet. –

+0

@ KamilMyśliwiec Ich habe die Login-Methode hinzugefügt. nur ein einfacher http bekommen. Es wird beim Drücken der Taste aufgerufen. Das einzige Problem ist, dass im Callback der Subskribierung die Daten im Session Service nicht gesetzt werden – perotom

Antwort

1

Dieser Code eine Funktion subscribe

 data => { 
      this._session.currentProfile = data; 
      this._session.loggedIn = true; 
      this._router.navigate(['Home']); 
     } 

Dieser Code ausgeführt wird, nicht sofort, aber manchmal später übergeben wird, wenn die Antwort vom Server kommt oder was auch immer Ereignis ist notwendig, damit das Observable ein neues Ereignis aussendet, das dann bewirkt, dass die obige Funktion aufgerufen wird.

Das bedeutet

login() { 
    this._auth.login(this.email, this.password) 
     .subscribe(
      data => { 
       this._session.currentProfile = data; 
       this._session.loggedIn = true; 
       this._router.navigate(['Home']); 
      }, 
      err => {} 
     ); 
    // <<== at this point above code hasn't been executed yet and no values are set 
} 

Wenn Sie Code müssen ausgeführt werden, wenn die Daten ankommen, müssen Sie es in den Rückruf bewegen.

Wenn der Anrufer von login Zugriff auf die empfangenen Daten benötigt, muss er ebenfalls warten, bis die Daten eintreffen. Sie können dies erreichen, indem die beobachtbaren

Rückkehr
login() { 
    return this._auth.login(this.email, this.password) 
     .map(
      data => { 
       this._session.currentProfile = data; 
       this._session.loggedIn = true; 
       this._router.navigate(['Home']); 
      } 
     ); 
} 

Sie nicht subscribe in diesem Fall benutzen kann, weil es eine Subscription zurückgibt. Wenn Sie map stattdessen verwenden, dann wird ein Observable zurückgegeben, die vom Anrufer verwendet werden kann, wie

this.login().subscribe(data => this.doSomething()); 

diese Weise, wenn doSomething() genannt wird, _session.currentProfile, _session.loggedIn gesetzt und router.navigate() aufgerufen wurde.

Die Async-Ausführung muss immer korrekt verkettet werden und es gibt keine Möglichkeit, die Ausführung eines Async-Aufrufs zu synchronisieren.

+0

ok clear. Vielleicht ist es ein anderes Problem. Wenn ich den Wert von 'this._session.loggedIn' direkt nach der Einstellung logge, ist es richtig, aber dann navigiere ich zu einer neuen Komponente' Home', in die ich den 'SessionService' noch einmal injiziere und dort den Wert von' this. _session.loggedIn' ist falsch. Ich dachte in angular2 alle Dienste sind Singleton? – perotom

+0

Sie scheinen die Werte nicht im Service zu speichern. Nur in der Komponente namens login() '. Services in Angular2 sind Singletons pro Anbieter. Wenn Sie es für eine Komponente bereitstellen, erhalten Sie eine Serviceinstanz für jede Komponenteninstanz. Wenn Sie es in einem Lazy-Loaded-Modul bereitstellen, erhalten Sie eine weitere Instanz, da Anbieter von Lazy Loaded-Modulen nicht in Root-Providern erfasst werden (sie besitzen einen eigenen Root-Bereich. Provider, die zu anderen '@NgModules()' hinzugefügt wurden) werden im Stammverzeichnis der Apps gesammelt Umfang und es wird nur eine einzige Instanz geben. –

+0

Ich denke, das ist das Problem. Also muss ich nur den Dienst mit '@ NgModules()' in 'app.module.ts 'registrieren und es sollte funktionieren? – perotom

Verwandte Themen