2016-12-30 51 views
7

我試圖在我的應用程序中實現一個身份驗證警衛。即;只有經過身份驗證的用戶才能訪問我的應用的某些路由我遵循給予here的tut。如何讓Angular2服務單例?

一旦用戶登錄,我將AuthService中的布爾值更改爲true,以指示使用已登錄。在應用程序的整個生命週期中需要保留哪些內容。

鑑於下面的源代碼:

AUTH-guard.service.ts

import { Injectable }  from '@angular/core'; 
import { 
    CanActivate, Router, 
    ActivatedRouteSnapshot, 
    RouterStateSnapshot 
}      from '@angular/router'; 
import { AuthService } from './auth.service'; 

@Injectable() 
export class AuthGuardService implements CanActivate { 
    constructor(private authService: AuthService, private router: Router) {} 
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {   
    let url: string = state.url; 
    return this.checkLogin(url); 
    } 

    checkLogin(url: string): boolean { 
    console.log('Auth Guard Service: ' + this.authService.isLoggedIn); 
    if (this.authService.isLoggedIn) { return true; } 
    // Store the attempted URL for redirecting 
    this.authService.redirectUrl = url; 

    // Navigate to the login page with extras 
    this.router.navigate(['/admin', 'admin-login']); 
    return false; 
    } 
} 

auth.service.ts

import { Injectable } from '@angular/core'; 
    import { Http } from '@angular/http'; 

    import { User } from '../user/shared/user.model'; 

    import { ServiceBase } from '../../core/service.base'; 
    import { appConfig } from '../../core/app.config'; 

    @Injectable() 
    export class AuthService extends ServiceBase { 
     public isLoggedIn: boolean = false; 
     redirectUrl: string; 
     apiUrl: string; 
     constructor(private http: Http) { 
      super(); 
      this.apiUrl = appConfig.apiBaseUrl + '/users/signin'; 
     } 
     signin(user: User, successCallback, errorCallback) { 
      return this.http.post(this.apiUrl, user).subscribe(
       res => { 
        this.isLoggedIn = true; 
        successCallback(res); 
       }, 
       err => { 
        //this.isLoggedIn = false; 
        errorCallback(err); 
       } 
      ); 
     }    
    } 

login.component.ts

import { Component, OnInit } from '@angular/core'; 
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; 
import { Router } from '@angular/router'; 
import { User } from '../../user/shared/user.model'; 
import { AuthService } from '../auth.service'; 

@Component({ 
    moduleId: module.id, 
    templateUrl: 'login.component.html' 
}) 
export class AdminLoginComponent implements OnInit{ 

    user: User; 
    userLoginForm: FormGroup; 

    constructor(
     private formBuilder: FormBuilder, 
     private authService: AuthService, 
     private router: Router){ 
     this.user = new User(); 
    } 

    ngOnInit(){ 
     this.buildLoginForm(); 
    } 
    buildLoginForm() { 
     ... 
    } 
    login() { 
     if(!this.userLoginForm.valid) return false; 
     this.authService.signin(this.user, 
      response => { 
       console.log('Login Component: ' + this.authService.isLoggedIn); 
       this.router.navigate(['/admin', 'products']); 
      }, 
      response => {} 
     ); 
    } 
} 

控制檯輸出

XHR finished loading: POST "http://localhost:3000/api/users/signin". 
login.component.ts:40 Login Component: true 
auth-guard.service.ts:23 Auth Guard Service: false 

編輯:app.module.ts

import { NgModule } from '@angular/core'; 
    ... 
    import { AuthGuardService } from './auth/auth-guard.service'; 
    import { AuthService } from './auth/auth.service'; 

    @NgModule({ 
     imports: [ 
      ... 
      AdminRoutingModule 
     ], 
     exports: [ 
     ], 
     declarations: [ 
      ... 
      AdminLoginComponent, 
      ... 
     ], 
     providers: [ 
      AuthGuardService, 
      AuthService, 
      ... 
     ], 
     bootstrap:[] 
    }) 
    export class AdminModule {} 

我在做什麼錯在這裏?任何幫助,將不勝感激。

+2

見讓你擁有所有的服務裏面加上''你的modules'部分providers'服務單。如果你在組件的'providers'部分添加了服務,那麼對於那個組件,新的服務實例將被初始化。 – ranakrunal9

+0

讓我們在哪裏添加此服務? App.module – Milad

回答

3

正如ranakrunal9所提到的,如果您在組件或指令中提供服務,則會爲每個此類組件實例獲得一個新實例。

您還將獲得一個用於延遲加載模塊的新實例(使用loadChildren加載)。延遲加載的模塊獲得它們自己的根作用域,並且如果在該延遲加載的模塊中提供該服務,則此模塊中的組件和服務將獲得不同的服務實例。

爲確保您的整個應用程序只有一個實例,請僅在AppModuleAppModule加載的模塊中直接或間接使用imports: [...]提供。

https://stackoverflow.com/a/40981772/217408

+1

我在我的子模塊(Admin Module)中提供了'AuthService'。正如你所建議的,我在'AppModule'中提供了'AuthService',現在一切正常。謝謝! –

+0

不客氣。很高興聽到你能使它工作。 –