有条件地在Angular路由器的空路径上加载模块

Ben*_*cot 7 javascript routing module angular

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

const routes: Routes = [
    { path: '', loadChildren: './home/home.module#HomeModule' }
...
Run Code Online (Sandbox Code Playgroud)

经过身份验证的用户应该通过该模块获取其Feed,也是在空路径上.

{ path: '', loadChildren: './feed/feed.module#FeedModule', canActivate: [IsAuthenticationGuard] },
{ path: '', loadChildren: './home/home.module#HomeModule', canActivate: [NoAuthenticationGuard] },
Run Code Online (Sandbox Code Playgroud)

我希望这IsAuthenticationGuard会失败并加载默认的主组件.

相反,它会下载Feed模块包(显示在网络选项卡中),但在路由器插座中没有任何内容.很混乱.

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

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

@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;
        }));
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经研究了新的urlTree,它很酷,你现在可以通过路线而不是在守卫内重定向.但是,如果您尝试使用具有不同模块的相同路由,则重定向似乎不适用.如果有办法,Plz纠正我.

Ben*_*cot 3

事实证明,直到 Ivy 之前,这基本上是不可能(安全地)实现的。现在,在 Angular 9/10 中,我们可以非常轻松地延迟加载功能模块,而无需路由器。

StackBlitz
V13 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();

            // Angular < 13 
            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);

            // Angular 13 update
            const moduleRef = createNgModuleRef(module, this.injector);
            const componentFactory = moduleRef.instance.resolveComponent();
            ref = container.createComponent(
                componentFactory,
                undefined,
                moduleRef.injector
            );

        } catch (e) {
            console.error(e);
        }
            return ref;
        }
    }
Run Code Online (Sandbox Code Playgroud)