重定向到Angular2中@CanActivate内的其他组件

时间:2016-01-10 23:12:09

标签: angular angular2-routing

我们有什么方法可以从Angular2中的@CanActivate重定向到另一个组件?

6 个答案:

答案 0 :(得分:53)

截至今天,使用最新的@ angular / router 3.0.0-rc.1,以下是关于如何通过路由上的CanActivate警卫执行此操作的几个参考:

  1. the documentation
  2. 此问题的两个答案,angular 2 referenceNilz11
  3. 逻辑的主要要点如下:

    // ...
    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;
      }
    }
    

答案 1 :(得分:13)

Angular 2.0最终解决方案:

您的警卫很容易成为一种注射剂,因此可以包含自己的注射剂。 所以我们可以简单地注入路由器,以便重定向。不要忘记在服务器模块中将服务添加为提供程序。

@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]}
];

答案 2 :(得分:12)

是的,你可以!这样做会阻止您的组件实例化。

首先,制作一个新文件src/app-injector.ts

let appInjectorRef;

export const appInjector:any = (injector = false) => {
    if (!injector) {
        return appInjectorRef;
    }

    appInjectorRef = injector;

    return appInjectorRef;
};

然后,从bootstrap

获取引用
// ...
import {appInjector} from './app-injector';
// ...


bootstrap(App, [
  ROUTER_PROVIDERS
]).then((appRef) => appInjector(appRef.injector));

最后在你的功能中

// ...
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;
})

Etvoilà!

这里讨论了https://github.com/angular/angular/issues/4112

您可以在@brandonroberts

找到http://plnkr.co/edit/siMNH53PCuvUBRLk6suc?p=preview的完整示例

答案 3 :(得分:2)

这可能有助于在继续之前尝试等待某事的人。

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;
    }
  }
)
}

答案 4 :(得分:1)

如果您使用观测值来确定,则可以利用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(['/']);
        }
      }));
  }

}

答案 5 :(得分:1)

从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']);
  }
}