2016-07-07 64 views
2

我想重定向到我的家庭組件認證後。重定向成功,但主頁組件不呈現。如果我將this.router.navigate移動到訂閱塊外部,它將正確呈現。路由器導航重定向後身份驗證不呈現組件

export class LoginComponent implements AfterViewInit { 
    constructor(private router: Router, 
       private authService: AuthenticationService) { 

     this.authService.authenticationStream().subscribe(isAuthenticated => { 
      if (isAuthenticated) { 
       this.router.navigate(['/home']); 
      } 
     }); 
    } 
} 

在Chrome瀏覽器開發工具,我可以看到所有的家庭成分的模板除了一個ngFor塊:

<md-grid-tile *ngFor="let tile of CONFIG.tiles"> 
    {{ tile }} 
</md-grid-tile> 

我可以驗證CONFIG.tiles填充。

爲什麼在導航後不會呈現ngFor塊,特別是在Observable訂閱中導航調用?

編輯:添加了AuthenticationService代碼:

export class AuthenticationService { 
    constructor(private http: HttpService, 
       private store: Store<AppStore>) { 
    } 

    authenticate(): void { 
     let uri = 'http://uri.com' 
     this.http.post(uri).subscribe(() => { 
      // Dispatch event to ngrx store if user is successfully authenticated 
      this.store.dispatch({type: AUTHENTICATED}); 
     }); 
    } 

    authenticationStream(): Observable<boolean> { 
     // Emits events from dispatch calls 
     return <Observable<boolean>> this.store.select(AUTHENTICATION); 
    } 
} 
+0

什麼是'authService'authenticationStream'? –

+0

'authService.authenticationStream()'返回一個表示驗證狀態的布爾值的Observable流 –

+0

請添加顯示它的代碼 –

回答

3

這聽起來像authenticationStream發出打破變化檢測,並會導致您所描述的行爲Angulars區域外的事件。

您可以使用zone.run()強制執行回Angulars區:

export class LoginComponent implements AfterViewInit { 
    constructor(private router: Router, 
       private authService: AuthenticationService 
       zone: NgZone) { 

     this.authService.authenticationStream().subscribe(isAuthenticated => { 
      if (isAuthenticated) { 
       zone.run(() => this.router.navigate(['/home'])); 
      } 
     }); 
    } 
} 
+0

我認爲可能值得研究爲什麼會發生這種情況,可能更適合使用'zone.run() '代碼開始在區域外運行,但爲此我需要看到更多的代碼('authService.authenticationStream'和使用它發出事件的地方)。 –

+0

Hey Gunter,zone.run做什麼?創建一個新的範圍? – inoabrian

+3

Angular2在區域內運行代碼。區域是一個範圍,其中(大多數)異步API('addEventHandler','removeEventHandler','setTimeout',...)被修補,以便在發生某些事件時通知Angular2。每當發生事件並且所有事件處理程序完成時,Angular2都會運行更改檢測。如果代碼在Angulars區域之外運行,則不會發生更改檢測,這會導致您描述的行爲。 'zone.run()'使一個執行線程(可能在Angulars區域之外)在其區域內繼續。 在使用某些未打補丁的異步API時,運行Angulars區域外的代碼。 –