[英]Redirect to a different component inside @CanActivate in Angular2
我们有什么方法可以从Angular2中的@CanActivate重定向到另一个组件吗?
As of today, with latest @angular/router 3.0.0-rc.1, here are a couple of references on how to do that through CanActivate
guards on routes: 截至今天,最新的@ angular / router 3.0.0-rc.1,以下是关于如何通过
CanActivate
上的CanActivate
防护来做到这一点的几个参考:
The main gist of logic looks like: 逻辑的主要要点如下:
// ...
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (this.authService.isLoggedIn) {
// all ok, proceed navigation to routed component
return true;
}
else {
// start a new navigation to redirect to login page
this.router.navigate(['/login']);
// abort current navigation
return false;
}
}
Your guard can easily just be an injectable which, as such, can include its own injectables. 您的护理人员可以很容易地成为一种注射剂,因此可以包含自己的注射剂。 So we can simply inject the router, in order to redirect .
所以我们可以简单地注入路由器,以便重定向 。 Don't forget to add the service as a provider in your app module.
不要忘记在您的应用模块中将服务添加为提供者。
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router, private authService: AuthService) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
if (!authService.isAuthenticated()) {
this.router.navigate(['/login']);
return false;
}
return true;
}
}
export const ROUTES: Routes = [
{path: 'login', component: LoginComponent},
{path: 'protected', loadChildren: 'DashboardComponent', canActivate: [AuthGuard]}
];
Yes, you can! 是的你可以! Doing this will prevent your component from instantiating for nothing.
这样做可以防止组件实例化。
First, make a new file src/app-injector.ts
首先,创建一个新文件
src/app-injector.ts
let appInjectorRef;
export const appInjector:any = (injector = false) => {
if (!injector) {
return appInjectorRef;
}
appInjectorRef = injector;
return appInjectorRef;
};
Then, get the reference from bootstrap
然后,从
bootstrap
获取引用
// ...
import {appInjector} from './app-injector';
// ...
bootstrap(App, [
ROUTER_PROVIDERS
]).then((appRef) => appInjector(appRef.injector));
Finally in your function 最后在你的功能
// ...
import {appInjector} from './app-injector';
// ...
@CanActivate((next, prev) => {
let injector = appInjector();
let router = injector.get(Router);
if (42 != 4 + 2) {
router.navigate(['You', 'Shall', 'Not', 'Pass']);
return false;
}
return true;
})
Et voilà ! Etvoilà!
It was discussed here https://github.com/angular/angular/issues/4112 这里讨论了https://github.com/angular/angular/issues/4112
You can find a complete example here http://plnkr.co/edit/siMNH53PCuvUBRLk6suc?p=preview by @brandonroberts 你可以在这里找到一个完整的例子http://plnkr.co/edit/siMNH53PCuvUBRLk6suc?p=preview by @brandonroberts
This might help someone who is trying to wait on something before continuing. 这可能有助于在继续之前尝试等待某事的人。
waitForBonusToLoad(): Observable<[boolean, string]> {
const userClassBonusLoaded$ = this.store.select(fromRoot.getUserClasssBonusLoaded);
const userClassSelected$ = this.store.select(fromRoot.getClassAttendancesSelectedId);
return userClassBonusLoaded$.withLatestFrom(userClassSelected$)
.do(([val, val2]) => {
if (val === null && val2 !== null) {
this.store.dispatch(new userClassBonus.LoadAction(val2));
}
})
.filter(([val, val2]) => {
if(val === null && val2 === null) return true;
else return val;
})
.map(val => {
return val;
})
.take(1);
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.waitForBonusToLoad().map(([val, val2]) =>
{
if(val === null && val2 === null){
this.router.navigate(['/portal/user-bio']);
return false;
}
else {
return true;
}
}
)
}
If you are using an observable to determine, you can leverage tap
operator from rxjs
: 如果您使用observable来确定,则可以利用
rxjs
tap
操作符:
@Injectable({
providedIn: SharedModule // or whatever is the equivalent in your app
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.authService.isLoggedIn()
.pipe(tap((isLoggedIn: boolean) => {
if (!isLoggedIn) {
this.router.navigate(['/']);
}
}));
}
}
As of Angular 7.1, you can return UrlTree
instead of boolean
: 从Angular 7.1开始,您可以返回
UrlTree
而不是boolean
:
@Injectable({
providedIn: 'root',
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) { }
canActivate(): boolean | UrlTree {
return this.authService.isAuthenticated() || this.router.createUrlTree(['/login']);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.