查找路径是否可导航到不导航到它

时间:2018-03-22 16:54:32

标签: angular angular2-routing

我希望根据路线是否可导航来绘制(或不绘制)导航菜单。即如果路由器的authGuards拒绝路由,则不会呈现它。

关键是能够询问路由器是否可以激活路由。

假设我有一个这样的routes.ts文件:

export const routes = [

    {
        path: '',
        component: LayoutComponent,
        children: [
            { path: 'tactics', component: IframeComponent, canActivate: [AuthGuard], data: { expectedRole: 'admin' } }
        ]
    }
];

authGuard可能会也可能不允许根据expectedRole属性激活路线“策略”

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(public auth: AuthService) {}

  canActivate(route: ActivatedRouteSnapshot): boolean {
    // expectedRole on the data property in route config
    const expectedRole = route.data.expectedRole;
    return auth.hasExpectedRole(expectedRole);
  }
}

如果可以导航到特定路径而不实际导航到路由器(或任何其他适当的服务),我该怎么办?请注意,authguard不仅仅是已登录而未登录,它使用路由中的数据属性“expectedRole”常量并检查此人是否已登录具有该权限

我想这样做是为了避免重复配置哪些路径需要哪些用户权限。

我知道我可以抓住路线不变并自己进行处理,但这感觉就像重做路由器已经做的那样,我几乎肯定得到了一些错误的

1 个答案:

答案 0 :(得分:0)

What you need is a custom structural directive. It can act like *ngIf, but based on AuthGuard logic.

You should extract AuthGuard logic into separate service and than inject it into your new structural directive.

class LoginService {
  isLoggedIn(): Observable<boolean> {
     return of(true)
  }
}

class AuthGuard implements CanActivate {
  constructor(public loginService: LoginService) {}

  canActivate() {
    return this.loginService.isLoggedIn();
  }
}

@Directive({
  selector: '[ifLoggedIn]',
})
export class LoggedInDirective implements OnInit, OnDestroy {
  subscription: Subscription;
  hasView: boolean;

  constructor(
    public loginService: LoginService,
    public viewContainerRef: ViewContainerRef,
    public templateRef: TemplateRef<any>,
  ) {}

  ngOnInit(): void {
    this.subscription = this.loginService.isLoggedIn()
      .subscribe(loggedIn => {
        if (loggedIn && !this.hasView) {
          this.viewContainerRef.createEmbeddedView(this.templateRef);
          this.hasView = true;
        }

        if (!loggedIn && this.hasView) {
          this.viewContainerRef.clear();
          this.hasView = false;
        }
      });
  }

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
  }
}