在使用路由器模块v 3.0.0.6alpha的angular2 rc2中,我扩展了RouterOulet以检查用户是否在登录之前登录。所以这是代码:
@Directive({
selector: 'router-outlet'
})
export class LoggedInRouterOutlet extends RouterOutlet
{
publicRoutes: Array<string>;
private parentOutletMap: RouterOutletMap;
private userService: UserService;
private parentRouter: Router;
constructor(
parentOutletMap: RouterOutletMap,
_location: ViewContainerRef,
@Attribute('name') name: string,
userService: UserService,
parentRouter: Router
) {
super(parentOutletMap, _location, name);
this.parentRouter = parentRouter;
this.parentOutletMap = parentOutletMap;
this.userService = userService;
this.publicRoutes = [
'public',
'login'
];
}
activate(factory: ComponentFactory<any>, activatedRoute: ActivatedRoute, providers: ResolvedReflectiveProvider[], outletMap: RouterOutletMap)
{
if (this._canActivate(factory.selector)) {
return super.activate(factory, activatedRoute, providers, outletMap);
}
this.parentRouter.navigate(['/login']);
}
_canActivate(url) {
return this.publicRoutes.indexOf(url) !== -1 || this.userService.isLoggedIn()
}
}
userService.isLoggedIn()必须返回一个布尔值。我的问题是:如何调整我的代码进行http调用以检查用户是否已登录?因为如果isLoggedIn方法返回一个可观察对象,并且我订阅它,我就无法在父函数中返回结果。
答案 0 :(得分:8)
请注意,OutletRouter的activate方法的结果已更改。
<强> @角/路由器弃用强>
activate(nextInstruction: ComponentInstruction) : Promise<any>
<强> @角/路由器强>
activate(factory: ComponentFactory<any>, providers: ResolvedReflectiveProvider[], outletMap: RouterOutletMap) : ComponentRef<any>
不再是Promise或Observable。新的路由器实现带来了一些我认为更清洁的解决方案:Guards。
后卫的返回值控制着路由器的行为:
如果返回true,导航过程会在返回时继续 false,导航过程停止,用户保持警惕 也可以告诉路由器在其他地方导航,有效取消 当前导航。
守卫可能会同步返回其布尔答案。但在很多方面 在这种情况下,警卫不能同步产生答案。守卫 可以向用户询问问题,保存对服务器的更改或获取 新鲜数据。这些都是异步操作。
因此,路由保护可以返回一个Observable和 路由器将等待observable解析为true或`false。
您可以创建auth.guard.ts:
import { Injectable } from '@angular/core';
import { CanActivate,
Router,
ActivatedRouteSnapshot,
RouterStateSnapshot } from '@angular/router';
import { UserService } from './user.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private userService: UserService, private router: Router) {}
canActivate(
// Not using but worth knowing about
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) {
return this.userService.isLoggedIn();
}
}
现在确保你的isLoggedIn返回Observable(或Promise - 同时尝试Angular2 Reference为not ready yet)。在我的情况下,API以格式返回JSON:{success:true / false}。
public isLoggedIn() : Observable<boolean> | boolean {
let router: Router = this.router;
let obs;
try {
obs = this.authHttp.get('/api/check/logged')
.map(result => result.json())
.map(resultJson => (resultJson && resultJson.success));
} catch (err) {
obs = Observable.of(false);
}
return obs
.map(success => {
// navigate to login page
if (!success)
router.navigate(['/auth/login']);
return success;
});
}
然后只需修改您的RouterConfig数组:
{ path: '/secret', component: SercetComponent, canActivate: [AuthGuard] }