我想通过角度2
中的路径调用页面在我的app.modules中,我使用了RouterModule和Routes,看起来很好看:
...
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { DashBoardComponent} from './dashboard/dashboard.component';
import { NotFoundComponent } from './not-found/not-found.component';
在这里,我创建了一个常量
const APPROUTES: Routes = [
{path: 'home', component: AppComponent},
{path: 'login', component: LoginComponent},
{path: 'dashboard', component: DashBoardComponent},
{path: '**', component: NotFoundComponent}
];
@NgModule({
declarations: [
AppComponent,
LoginComponent,
DashBoardComponent
NotFoundComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
MaterialModule.forRoot(),
RouterModule.forRoot(APPROUTES)
],
providers: [],
bootstrap: [AppComponent]
})
我最初有两个页面,仪表板和登录,我想加载第一个登录页面和afeter仪表板页面,如果有其他条件......
在主页面“appcomponent.ts”中,如何进行此操作是条件登录和仪表板前
if(loggedin){
// page dashboard
}else{
// page login
}
答案 0 :(得分:64)
以下是3种方式来做你所问的,从最不喜欢到最喜欢的方式:
选项1.强制重定向用户AppComponent
@Component({
selector: 'app-root',
template: `...`
})
export class AppComponent {
constructor(authService: AuthService, router: Router) {
if (authService.isLoggedIn()) {
router.navigate(['dashboard']);
}
}
}
不是很好。最好将“需要登录”信息保存在它所属的路径声明中。
选项2.使用CanActivate
后卫
为需要用户登录的所有路线添加CanActivate
防护:
const APPROUTES: Routes = [
{path: 'home', component: AppComponent, canActivate:[LoginActivate]},
{path: 'dashboard', component: DashBoardComponent, canActivate:[LoginActivate]},
{path: 'login', component: LoginComponent},
{path: '**', component: NotFoundComponent}
];
我的警卫称为LoginActivate
。
要使它工作,我必须将守卫添加到我的模块的providers
。
然后我需要实现它。在这个例子中,我将使用guard来重定向用户,如果他们没有登录:
@Injectable()
export class LoginActivate implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
if (!this.authService.isLoggedIn()) {
this.router.navigate(['login']);
}
return true;
}
}
如果没有意义,请查看关于路线保护的文档:https://angular.io/docs/ts/latest/guide/router.html#guards
此选项更好,但不够灵活。如果我们需要检查除“登录”之外的其他条件,例如用户权限,该怎么办?如果我们需要将一些参数传递给后卫,例如角色“admin”,“editor”的名称,该怎么办?
选项3.使用路线data
属性
最佳解决方案恕我直言在路线声明中添加一些元数据,以指示“此路线要求用户登录”。
我们可以使用路由data
属性。它可以保存任意数据,在这种情况下,我选择包含一个requiresLogin
标志true
或false
(如果未定义标志,false
将是默认值) :
const APPROUTES: Routes = [
{path: 'home', component: AppComponent, data:{requiresLogin: true}},
{path: 'dashboard', component: DashBoardComponent, data:{requiresLogin: true}}
];
现在data
属性本身没有做任何事情。但我可以用它来强制执行我的“需要登录”逻辑。为此,我需要再次CanActivate
警卫。
太糟糕了,你说。现在我需要为每个受保护的路由添加两个东西:元数据和守卫......
BUT:
CanActivate
后卫附加到顶级路线,将为其所有子路线 [待确认]执行。这样你只需要使用一次守卫。当然,它只有在要保护的路线都是父路线的孩子时才有效(在Rafael Moura的例子中并非如此)。data
属性允许我们将各种参数传递给警卫,例如要检查的特定角色或权限的名称,用户访问页面时需要拥有的点数或信用等等。考虑到这些评论,最好将警卫重命名为AccessGuard
等更通用的内容。
我只会显示守卫检索路线附近data
的代码,因为你在守卫内部所做的事情取决于你的情况:
@Injectable()
export class AccessGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot): Observable<boolean>|Promise<boolean>|boolean {
const requiresLogin = route.data.requiresLogin || false;
if (requiresLogin) {
// Check that the user is logged in...
}
}
}
要执行上述代码,您需要具有类似于:
的路由{
path: 'home',
component: AppComponent,
data: { requiresLogin: true },
canActivate: [ AccessGuard ]
}
NB。不要忘记将AccessGuard
添加到模块的providers
。
答案 1 :(得分:0)
您还可以执行以下操作:
{
path: 'home',
component: getHomeComponent(),
data: { requiresLogin: true },
canActivate: [ AccessGuard ]
}
然后:
export function getHomeComponent(): Type<Component> {
if (User.isLoggedIn) {
return <Type<Component>>HomeComponent;
}
else{
return <Type<Component>>LoginComponent;
}
}