首页 文章

Angular2 observables - 订阅不会在用户登录时更新我的变量

提问于
浏览
3

因此,当用户登录时,我正在尝试更新我的菜单 . 我已经阅读了几个关于类似问题的答案,但我仍然无法让它工作 .

nav-bar.component.html:

<li *ngIf="isLoggedIn"><a routerLink="/" (click)="logout($event);"> {{ logoutLabel }}</a></li>
<li *ngIf="!isLoggedIn"><a routerLink="/login (click)="showPopup($event);">{{ loginLabel }}</a></li>

nav-bar.component.ts 中,我使用登录表单打开一个模态,并在 login.service 中查找变量的变化

import { SuPopupLoginComponent } from '../shared/su-popup-login/su-popup-login.component';
import { LoginService } from '../login/login.service';
...imports...

@Component({
   selector: 'app-nav-bar',
   templateUrl: './nav-bar.component.html',
   styleUrls: ['./nav-bar.component.scss']
})
export class NavBarComponent implements OnInit {
  loginLabel: string;
  public isLoggedIn: boolean;

   constructor(private loginService: LoginService, private suPopupLoginComponent: SuPopupLoginComponent) {
      loginService.getIsLoggedIn.subscribe((bool: boolean) => {
         this.isLoggedIn = bool;
         console.log('NavBarComponent', this.isLoggedIn);
      });
   }

   showPopup(event) {
      event.preventDefault();
      this.suPopupLoginComponent.showPopup();

      If I call login here It works just as expected

      // this.loginService.login('test@test.se', 'Test123')
      //      .subscribe(
      //        data => {
      //          if (data) { // If login was successful data is true.
      //            let redirect = 'license-overview';
      //            this.router.navigate([redirect]);

      //          } 
      //        }
      //      );
  }  

   logout(event) {
      event.preventDefault();
      this.loginService.logout();
   }
   ngOnInit() { }
}

su-popup-login.component.ts - 登录表单并调用登录功能:

import { LoginService } from '../../login/login.service';
import { Injector } from '@angular/core';

@Component({
  selector: 'su-popup-login',
  templateUrl: './su-popup-login.component.html',
  styleUrls: ['./su-popup-login.component.scss'],
  providers: [LoginService]
})

export class SuPopupLoginComponent implements OnInit {

   constructor(private loginService: LoginService, private injector: Injector) { }

   public showPopup() {
     Css and showing modal
   }

   login(event, mail, password) {
      this.loginService.login(mail, password)
         .subscribe(
            data => {

              if (data) { // If login was successful data is true.

              // Navigate to view after login success.
              this.router = this.injector.get(Router);
              let redirect = 'license-overview';
              this.router.navigate([redirect]);

        }
      }
    );
   }

login.service.ts

import { Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class LoginService {
   private isLoggedInSource = new BehaviorSubject<boolean>(localStorage.getItem('currentUser') ? true : false);
   public _isLoggedIn: Observable<boolean> = this.isLoggedInSource.asObservable();

   constructor(private http: Http) { }

   private isLoggedIn(logged: boolean) {
      this.isLoggedInSource.next(logged);
   }

   get getIsLoggedIn() {
      return this._isLoggedIn;
   }

   login = (mail: string, password: string): Observable<boolean> => {
   let loginUrl = '/api/authenticate';
   let body = JSON.stringify({ mail, password });

   return this.http.post(loginUrl, body)
      .map((response: Response) => {
          let user = response.json();

          if (user && user.tokenId) {
            this.isLoggedIn(true);

            // Add to local storage
           localStorage.setItem('currentUser', JSON.stringify({ mail: mail, tokenId: user.tokenId }));
           return true;  // Login success
         }
         else {
           return false; // Login failed
         }
      });
   }
}

如果我从 nav-bar.component 调用 this.loginService.login('user', 'pass') ,它可以正常工作,但是当从 su-popup-login.component.ts 调用login时不行 . 此外,来自 nav-bar.component.tsthis.loginService.logout() 工作正常 .

订阅调用是否必须与登录/注销调用位于同一组件中?如果是这样,我想我只是不明白Observables是如何工作的 .

感谢任何帮助或评论 .

1 回答

  • 1

    providers: [LoginService]su-popup-login.component.ts 中创建了 LoginService 的不同实例 .

    要使其工作,您必须确保两个组件共享 LoginService 的单个实例

    为避免这种情况,请在 ngModule of appcomponentcoremodule 中使用 providers: [LoginService] 并从 su-popup-login.component.ts 删除 providers: [LoginService]

相关问题