在文件 auth-guard-service.ts 中,为什么调用this.router.navigateByUrl('/ login')无法正常工作,同时警告消息打印?另一个文件( auth.service.ts )中的另一个调用正常工作。
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 :(得分:1)
从angular documentation,&#34;始终指定完整 调用路由器的navigateByUrl方法时的绝对路径。&#34;
改为使用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']);
}
);
}
);
}
答案 1 :(得分:0)
简短的解决方案(没有警报())是替换
this.router.navigate(['/login']);
通过
observer.next(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()等...)。
PS:我不是Angular2 / NodeJS / Callback / Promise / Observable的高手,所以我不确定答案。如果您有所了解,请随时回答。 :)
答案 2 :(得分:0)
这是我的答案。 subscription方法采用3个参数,下一个,错误和完成。订阅方法完成后重定向。在这种情况下,它将转到仪表板组件。
login() {
this.authService.logIn(this.model).subscribe(
next => {
this.alertify.success('Logged in successfully');
},
error => {
this.alertify.error(error);
},
() => {
this.router.navigate(['/dashboard']);
}
);
}