2017-08-17 76 views
2

在文件auth-guard-service.ts,为什么在打印警告消息时调用this.router.navigateByUrl('/ login')不起作用?在另一个文件中的另一个电话(auth.service.ts)能正常工作。Angular2:可观察订阅失败时如何重定向到登录页面?

AUTH-护service.ts

import { Injectable }   from '@angular/core'; 
import { CanActivate, Router } from '@angular/router'; 
import { Observable }   from 'rxjs'; 
import { Domain }    from 'domain'; 
import { AuthService }   from './auth.service'; 

@Injectable() 
export class AuthGuardService implements CanActivate { 
    private domain: Domain = new Domain(); 

    constructor(private router: Router) {} 

    public canActivate(): Observable<boolean>|Promise<boolean>|boolean { 
      return Observable.create(
       (observer) => { 
        this.domain.isauth() 
        .subscribe(
         (res) => { 
          observer.next(true); 
         }, 
         (err) => { 
          alert('You need to be authentificated to access this content'); 
          // The call to navigateByUrl below does not work. To fix. 
          this.router.navigateByUrl('/login'); 
         } 
        ); 
       } 
      ); 
     } 

auth.service.ts

import { Injectable }  from '@angular/core'; 
import { Router }   from '@angular/router'; 
import { Observable }  from 'rxjs'; 
import { Domain }   from 'domain'; 
import { ConfigService } from './config.service'; 

@Injectable() 
export class AuthService { 
    private authObject: Observable<boolean>; 
    private domain: Domain = new Domain(); 

    constructor(private router: Router) {} 

    public login(login: string, password: string) : void { 
     this.authObject = this.domain.auth(login, password); 
     alert('Connecting... Please wait.'); 
     this.authObject.subscribe(
      (value) => { 
       this.router.navigateByUrl('../view/dashboard'); 
      } 
     ); 
    } 

    public logout() : void { 
     alert('Going to logout...'); 
     this.domain.logout(); 
     this.router.navigateByUrl('/login'); 
    } 
} 

app.routing.ts

import { ModuleWithProviders } from '@angular/core'; 
import { 
    Routes, 
    RouterModule 
}        from '@angular/router'; 
import { LoginComponent }  from './login'; 
import { 
    DashboardComponent, 
    ViewComponent 
}        from './view'; 
import { AuthGuardService }  from './services'; 
const appRoutes: Routes = [ 
    { 
     path: 'view', 
     component: ViewComponent, 
     canActivate: [AuthGuardService], 
     children: [ 

      { 
       path: 'dashboard', 
       component: DashboardComponent 
      } 
      { 
       path: '', 
       redirectTo: 'dashboard', 
       pathMatch: 'full' 
      } 
     ] 
    }, 
    { 
     path: 'login', 
     component: LoginComponent 
    } 
    { 
     path: '**', 
     redirectTo: 'view' 
    } 
]; 

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes, { useHash: true }); 

在如果我遇到错误(如果用户没有连接),我只想重定向到登录页面。

配置:Angular2

+0

你可以发布你的'路线'文件 – vistajess

+0

@vistajess完成,我编辑帖子 –

+0

我没有看到任何错误的语法或代码中的实现。你是否在构造函数中注入了'Router'? – vistajess

回答

0

短期解决方案(无警报())是由

observer.next(this.router.navigate(['/login'])); 

更换

this.router.navigate(['/login']); 

或者,如果我想保留提醒信息:

observer.next(false); 
alert('You need to be authentificated to access this content'); 
this.router.navigateByUrl('/login'); 
  • 简短说明:

我们需要调用observer.next()才能解锁回调堆栈并执行下一回调指令;

  • 更详细的解释:

1)如果你在看代码,我订阅了一个观察者。在出现错误的情况下,没有执行下一个回调的指令,所以堆栈可能被“阻塞”。

2)根据documentation,navigateByUrl()是Promise,它通过回调工作。所以navigateByUrl()可能需要先前的观察者先被“解除封锁”,然后依次执行。

3)我们可能会想知道为什么alert()没有任何问题可以在两条指令位于同一个块的同时打印出错信息。原因可能是因为Node在不同的队列中执行打印堆栈(alert(),console.log()等)。我不是Angular2/NodeJS/Callback/Promise/Observable的主人,所以我不确定答案。如果你知道一些事情,请随时回答。 :)

1

angular documentation “总是呼叫路由器的navigateByUrl方法时指定完整 绝对路径”

使用router.navigate代替:

public canActivate(): Observable<boolean>|Promise<boolean>|boolean { 
      return Observable.create(
       (observer) => { 
        this.domain.isauth() 
        .subscribe(
         (res) => { 
          observer.next(true); 
         }, 
         (err) => { 
          alert('You need to be authentificated to access this content'); 
          // The call to navigateByUrl below does not work. To fix. 
          this.router.navigate(['/login']); 
         } 
        ); 
       } 
      ); 
     } 
+0

我也试过,但它不起作用 –

相关问题