在Angular路由器的空路径上有条件地加载模块 [英] Conditionally load module on the empty path in Angular router

查看:47
本文介绍了在Angular路由器的空路径上有条件地加载模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为未通过身份验证的访问者加载应用程序的主页.

I'm trying to load the home page of my app for visitors who are not authenticated.

const routes: Routes = [
    { path: '', loadChildren: './home/home.module#HomeModule' }
...

经过认证的用户应该通过该模块获取其供稿,并且该路径也应位于空路径上.

Authenticated users should get their feed via that module, also on the empty path.

{ path: '', loadChildren: './feed/feed.module#FeedModule', canActivate: [IsAuthenticationGuard] },
{ path: '', loadChildren: './home/home.module#HomeModule', canActivate: [NoAuthenticationGuard] },

我希望 IsAuthenticationGuard 失败并加载默认的home组件.

I would expect that IsAuthenticationGuard would fail and load the default home component.

相反,它确实下载了馈送模块软件包(显示在网络"选项卡中),但未在路由器插座中加载任何内容.非常混乱.

Instead it DOES download the feed module package (shown in the network tab) but loads nothing in the router outlet. Very confusing.

如何在空路径上进行条件路由(基于警卫或其他方式)?

更新:这是应要求提供的警卫

Update: Here are the guards by request

@Injectable()
export class IsAuthenticationGuard implements CanActivate {
    constructor(
        private authenticationService: AuthenticationService
    ) { }

    public canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ): Observable<boolean> {
        return this.authenticationService.isAuthenticated.pipe(take(1), map((isAuthentication) => {
            return isAuthentication;
        }));
    }
}

我已经研究了新的 urlTree ,这很酷,您现在可以通过路由而不是在防护网中进行重定向.但是,如果您尝试将相同的路由用于其他模块,则重定向似乎不适用.请允许我纠正.

I've researched the new urlTree and it's cool that you can now redirect via the route instead of within the guard. However, redirects don't seem applicable if you're trying to use the same route with a different module. Plz correct me if there is a way.

推荐答案

事实证明,直到Ivy,这基本上是(安全)可行的.现在,在Angular 9/10中,我们可以很容易地在没有路由器的情况下延迟加载功能模块.

It turns out that this was basically not (safely) possible until Ivy. Now in Angular 9/10 we can lazy load feature-modules without the router very easily.

StackBlitz

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
})
export class AppComponent implements OnInit  {
  @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;

  constructor( 
    private compiler: Compiler,
    private injector: Injector
  ){  }

  public ngOnInit(): void {
      if (loggedin) {
          this.loadModule(await import('./lazy/lazy.module').then(m => m.LazyModule));
      } else {
          this.loadModule(await import('./lazy2/lazy2.module').then(m => m.Lazy2Module));
      }
  }

  async loadModule(module: Type<any>) {
      let ref;
      try {
          this.container.clear();
          const moduleFactory = await this.compiler.compileModuleAsync(module);
          const moduleRef: any = moduleFactory.create(this.injector);
          const componentFactory = moduleRef.instance.resolveComponent(); // ASSERTION ERROR
          ref = this.container.createComponent(componentFactory, null, moduleRef.injector);
      } catch (e) {
          console.error(e);
      }
      return ref;
  }
}

这篇关于在Angular路由器的空路径上有条件地加载模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆