2016-12-30 12 views
7

私はアプリケーションで認証ガードを実装しようとしています。すなわち、認証されたユーザーだけが自分のアプリの特定のルートにアクセスできます。私はhere与えられたツタンツに従っています。Angular2 Serviceシングルトンを作る方法?

ユーザーがログインすると、自分の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

を参照してください。コンポーネントの 'providers'セクションの中にサービスを追加した場合、そのコンポーネントに対して新しいサービスインスタンスが初期化されます。 – ranakrunal9

+0

私はこのサービスをどこに追加したのですか? App.module – Milad

答えて

3

ranakrunal9で述べたように、コンポーネントまたはディレクティブでサービスを提供すると、そのようなコンポーネントインスタンスごとに新しいインスタンスが作成されます。

遅延ロードモジュール(loadChildrenがロードされている)の新しいインスタンスも取得します。遅延ロードされたモジュールは独自のルートスコープを取得し、このモジュール内のコンポーネントとサービスは、その遅延ロードされたモジュール内にそのサービスが提供されている場合、異なるサービスインスタンスを注入します。

アプリケーション全体で1つのインスタンスのみを確保するには、AppModuleまたはAppModuleによって直接または間接的にimports: [...]を使用してロードしたモジュールでのみ提供してください。

はあなた `modules`のproviders`セクション`内部ですべてのサービスを追加する必要があるサービスのシングルトンを作成することもhttps://stackoverflow.com/a/40981772/217408

+1

サブモジュール(Admin Module)に 'AuthService'を提供しました。私が 'AppModule'に' AuthService'を提供してほしいと提案したように、今はすべて正常に動作します。ありがとうございました! –

+0

ようこそ。あなたがそれを働かせることを聞いてうれしいです。 –

関連する問題