2017-10-11 163 views
0

我的authservice有問題。如果我在構造函數中創建一個http請求,它被稱爲259次。 如果我刪除了http調用,它會被調用一次。我使用共享模塊來提供該服務的唯一實例。角度4服務構造問題

角版本:4.4.4

Console print

這裏是我的sharedModule:

export const providers = [ 
 
    AuthService, 
 
    DataStorageService, 
 
]; 
 

 
@NgModule({ 
 
    imports: [ 
 
    CommonModule, 
 
    FormsModule, 
 
    HttpClientModule, 
 
    ReactiveFormsModule, 
 
    InfiniteScrollModule, 
 
    TruncateModule 
 
    ], 
 
    declarations: [ 
 
    FooterComponent, 
 
    PhotoListComponent, 
 
    GalleryListComponent, 
 
    ], 
 
    exports: [ 
 
    FooterComponent, 
 
    PhotoListComponent, 
 
    GalleryListComponent, 
 
    InfiniteScrollModule, 
 

 
    ], 
 
    providers: [ 
 
    
 
    ]}) 
 

 
export class SharedModule { 
 
    static forRoot(): ModuleWithProviders { 
 
    return { 
 
     ngModule: SharedModule, 
 
     providers: [...providers] 
 
    }; 
 
    } 
 
}

而且我AuthService:

@Injectable() 
 
export class AuthService { 
 

 
    public session: Subject<SessionModel> = new Subject<SessionModel>(); 
 
    private cachedSession: SessionModel = new SessionModel(null, null, false); 
 
    private apiUrl = 'http://localhost:8080/Galleo/user/login'; 
 

 

 
    constructor(private cookieSrv: CookieService, 
 
       private http: HttpClient) { 
 
    console.log('constructor called'); 
 
    if (this.cookieSrv.get('system-g-unx-data')) { 
 
     const cook = atob(this.cookieSrv.get('system-g-unx-data')).split('||'); 
 
     const username = cook[0]; 
 
     const password = cook[1]; 
 
     this.login(username, password); 
 
    } 
 
    } 
 

 
    // login method, call REST API and store cookie into user Browser 
 
    login(username: string, password: string) { 
 

 
    const user: UserModel = new UserModel(); 
 
    user.userName = username; 
 
    user.password = password; 
 

 
    const headers = new HttpHeaders(); 
 
    headers.append('Content-Type', 'application/json'); 
 

 
    this.http.post<UserModel>(this.apiUrl, user, {observe: 'response', headers: headers}).subscribe(
 
     (response) => { 
 
     console.dir(response); 
 
     this.cachedSession.user = response.body; 
 
     this.cachedSession.token = response.headers.get('Authorization'); 
 
     this.cachedSession.isAuthenticated = true; 
 
     this.session.next(this.cachedSession); 
 
     this.cookieSrv.put('system-g-unx-data', btoa(username + '||' + password)); 
 
     }, 
 
     (error) => { 
 
     console.dir(error); 
 
     this.session.next(null); 
 
     } 
 
    ); 
 
    } 
 
    }

謝謝!

編輯:我發現了這個問題。 來自AuthInterceptor。當我嘗試獲得授權令牌它開始一個無限循環:

@Injectable() 
 
export class AuthInterceptor implements HttpInterceptor { 
 
    private authService: AuthService; 
 
    constructor(private injector: Injector) {} 
 

 
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
 
    console.log('Intercepted!', req); 
 
    this.authService = this.injector.get(AuthService); 
 

 
    const request = req.clone({ 
 
     setHeaders: { 
 
     Authorization: `${this.authService.getSession().token}` 
 
     } 
 
    }); 
 

 
    return next.handle(request); 
 

 
    } 
 
}

現在我該怎麼恢復裏面攔截器authService不使用注射器?

FINAL EDIT: 我想出瞭如何從我的authService獲取令牌而不發生無限循環。 問題是我用於爲每個請求添加令牌到Authorization Header的HttpInterceptor。 在我AuthService構造我打電話的登錄方法,使一個HTTP請求.. LOOP:攔截器=> AUTH SERVICE => HTTP客戶端,並再次攔截器

所以,現在我做一些檢查在我喜歡的攔截:

Injectable() 
 
export class AuthInterceptor implements HttpInterceptor { 
 
    private authService: AuthService; 
 
    constructor(private injector: Injector) { } 
 

 
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
 

 
    // If login method called skip and continue request 
 
    if (req.url.includes('login')) { 
 
     return next.handle(req); 
 
    } 
 

 
    // If request don't have the Authorization Header, add the token to the header 
 
    if (!req.headers.has('Authorization')) { 
 
     this.authService = this.injector.get(AuthService); 
 
     const request = req.clone({ 
 
     setHeaders: { 
 
      Authorization: `${this.authService.getSession().token}` 
 
     } 
 
     }); 
 
     return next.handle(request); 
 
    } 
 

 
    return next.handle(req); 
 
    }

也許可以幫助別人,這將有同樣的問題。 PS:注射器需要在檢查後調用

感謝您的幫助!

+0

在docs一個單引用的「在ES6類(或打字原稿在這種情況下)的構造方法是一類本身的特徵,而不是一個Angular功能「:https://toddmotto.com/angular-constructor-ngoninit-lifecycle-hook 考慮使用'constructor'主要用於依賴注入,使用'ngOnInit'代替你的邏輯 –

+0

ngOnInit不被調用服務... –

回答

1

,你在你的app.module.ts

import { CommonModule } from '@angular/common'; 
import { 
    ModuleWithProviders, NgModule, 
    Optional, SkipSelf 
} from '@angular/core'; 


import { AuthGuard } from '../guards/auth.guard'; 
import { AuthService } from '../services/auth.service'; 

@NgModule({ 
    imports: [CommonModule], 
    declarations: [], 
    exports: [], 
    providers: [AuthGuard, AuthService] 
}) 

export class CoreModule { 

    constructor(@Optional() @SkipSelf() parentModule: CoreModule) { 
    if (parentModule) { 
     throw new Error(
     'CoreModule is already loaded. Import it in the AppModule only'); 
    } 
    } 

    static forRoot(): ModuleWithProviders { 
    return { 
     ngModule: CoreModule, 
     providers: [ 
     AuthService, 
     AuthGuard, 
     ] 
    }; 
    } 
} 

一次導入它有一個檢查,以確保它僅加載一次創建一個核心/ core.module.ts。

app.module。TS

import {CoreModule} from './core/core.module'; 

@NgModule({ 
    declarations: [ 
    ], 
    imports: [ 
    CoreModule.forRoot(), 
    ], 
    providers: [ 

    ], 
    bootstrap: [AppComponent] 
}) 

其作爲在「核心模塊」 https://angular.io/guide/ngmodule

+0

這不起作用..是同樣的事情..你試圖做一個http請求裏面?我需要聲明的http客戶端? –