簡體   English   中英

Angular 5將服務注入組件

[英]Angular 5 injecting services into components

我的身份驗證服務+組件存在問題,因為每次加載auth組件時,該服務似乎都會重新初始化。 我的應用程序中應該存在的流程是,根應用程序組件應在應用程序啟動時發送登錄請求,以檢查當前會話是否已通過身份驗證。 此登錄請求是從auth-service發送的。 auth-service的主題廣播一個布爾值,該布爾值指示用戶是否通過身份驗證,具體取決於登錄/注銷操作的結果。

除一種情況外,這非常有用。 如果我在身份驗證頁面上啟動該應用程序,請離開該組件並返回到該組件,則無法從該服務獲得正確的身份驗證狀態(真/假)。 由於某些原因,打印時的字段(服務中)狀態未定義。 為了調試,我什至在ngOnInit函數中插入了console.logs來查看是否有任何組件/服務被重新初始化,但是什么也沒有。

以下是app.component.ts (根組件)的外觀示例代碼:

constructor(private requestService: RequestService,
              private authService: AuthService) {}

  ngOnInit() {
    console.log("App component init");
    this.requestService.get('http://localhost:8000/api/csrf/')
      .subscribe(
        success => {
          this.authService.login('', '');
        }
    );
  }

第一次CSRF檢查的結果是觸發了登錄請求,到目前為止效果良好。

auth.service.ts

@Injectable()
export class AuthService implements OnInit, OnDestroy {
  authenticated: boolean;
  authSubject: Subject<boolean>;

  constructor(private requestService: RequestService) {
    console.log("Auth service constructor");
    this.authSubject = new Subject<boolean>();
  }

  ngOnInit() {
    console.log("Auth service init");
    this.authSubject.subscribe(
      next => {
        this.authenticated = next;
      }
    );
  }

  login(username: string, password: string) {
    console.log("Auth service login");
    this.requestService.post(LOGIN_URL, { username: username, password: password })
      .subscribe(
        next => {
          this.authSubject.next(true);
          console.log("[AuthService] Success logging in.");
        },
        error => {
          console.log("[AuthService] Error logging in.");
        },
        () => {
          console.log("[AuthService] Auth service completed.");
        }
      );
  }

  logout() {
    this.requestService.post(LOGOUT_URL, {})
    .subscribe(
      next => {
        this.authSubject.next(false);
        console.log('[AuthService] Success logging out.');
      },
      error => {
        console.log("[AuthService] Error logging out.");
      },
      () => {
        console.log("[AuthService] Auth service completed.");
      });
  }

  isAuthenticated(): boolean {
    return this.authenticated;
  }

  ngOnDestroy() {
    console.log("Auth service destroyed");
    this.authSubject.unsubscribe();
  }
}

正如上面您所看到的,我們開始了這里的工作,我不得不在構造函數而不是ngOnInit中實例化Subject。 這是因為從app.component.ts觸發登錄時,尚未創建主題,這會導致崩潰。 雖然這仍然有效。

auth.component.ts

export class AuthComponent implements OnInit {
  authenticated: boolean;

  constructor(private authService: AuthService) { }

  ngOnInit() {
    console.log("Auth component init");
    this.authService.authSubject.subscribe(
      next => {
        this.authenticated = next;
      }
    );
    this.authenticated = this.authService.isAuthenticated();
    console.log(this.authenticated);
  }

  onLogin(form: NgForm) {
    const username = form.value.username;
    const password = form.value.password;
    this.authService.login(username, password);
  }

  onLogout() {
    this.authService.logout();
  }

所以,這就是我被困住的地方。 登錄時,看到我已成功獲得響應,並且authenticated = true。 但是,當我離開auth視圖並返回到該視圖時,從authService.isAuthenticated獲取身份驗證的值使我回到“未定義”狀態! 該服務在那里並且完好無損(我進入ngOnDestroy進行該服務,那里什么也沒有觸發),所以我猜測存在參考問題或其他問題,我只是在文檔中找不到任何可以幫助我的東西。

請指教。

嘗試使用BehaviorSubject而不是Subject BehaviorSubject將播出訂閱前的最后一個值以及任何新值,而主題只會在您訂閱后播出任何新數據。

Subject和BehaviorSubject有什么區別?

問題在於ngOnInit沒有為角度服務調用,因此該訂閱從未在auth服務中激活。 當我將預訂移到服務構造函數時,所有工作都成功了!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM