Angular 角度5-对不同模块使用相同的路径

Angular 角度5-对不同模块使用相同的路径,angular,angular5,server-side-rendering,angular-universal,Angular,Angular5,Server Side Rendering,Angular Universal,如果你们碰巧是facebook用户,你可能会注意到当用户登录或注销时,Url“”不会改变。在我正在构建的一个应用程序(使用angular 5)中,我遇到了同样的问题。尽管有一些建议的解决方案: 首先是使用相同的路由,一个组件(比如:home),在home的模板中,我们用*ngIf插入in、out(组件),在运行时我们检查用户是否登录或注销,并根据这一点显示相应的(in或out)组件 home.component.html 这是matcher函数: export function matcherF

如果你们碰巧是facebook用户,你可能会注意到当用户登录或注销时,Url“”不会改变。在我正在构建的一个应用程序(使用angular 5)中,我遇到了同样的问题。尽管有一些建议的解决方案:

  • 首先是使用相同的路由,一个组件(比如:home),在home的模板中,我们用*ngIf插入in、out(组件),在运行时我们检查用户是否登录或注销,并根据这一点显示相应的(in或out)组件
  • home.component.html

    这是matcher函数:

    export function matcherFunc(url: UrlSegment[]) {
      let currentUser;
    
    
        currentUser = localStorage.getItem('user');
    
      if (url.length === 0 && currentUser) {
        return ({ consumed: url });
      } else {
        return null;
      }
    }
    
    当我将我的应用升级为通用时,问题变得更糟,因为在那种情况下,我必须在服务器端处理全局变量(窗口、本地存储等),我完全被困在那里


    我相信这个问题已经存在了一段时间,现在没有令人满意的答案,有什么建议吗?

    您可以使用一个模块,通过使用Angular的useFactory提供程序提供RouterModule的路由来处理应该加载的模块

    代码可能是这样的

    // HandlerModule
    
    @NgModule({
      declarations: [],
      imports: [
        CommonModule,
        RouterModule
      ],
      providers: [
        {
          provide: ROUTES,
          useFactory: configHandlerRoutes,
          deps: [SessionService],
          multi: true
        }
      ]
    })
    
    
    export class HandlerModule {}
    
    export function configHandlerRoutes(sessionService: SessionService) {
      let routes: Routes = [];
      if (sessionService.isLoggedIn()) {
        routes = [
          {
            path: '', loadChildren: './in/in.module#InModule'
          }
        ];
      } else {
        routes = [
          {
            path: '', loadChildren: './out/out.module#OutModule'
          }
        ];
      }
      return routes;
    }
    
    然后在AppRoutingModule中,路径“”的模块将成为HandlerModule:

    // AppRoutingModule
    
     {
        path: '',
        loadChildren: './handler/handler.module#HandlerModule'
     }
    
    进入SessionService后,当提供方法isLoggedIn的值更改时,您必须更新Router.config,因为应用程序将只加载第一次加载的页面(模块)。这是因为useFactory提供程序在HandlerModule中使用的函数“configHandlerRoutes”仅在我们第一次导航到“”路径时执行,之后角度路由器已经知道他必须加载哪个模块

    总之,在SessionService中,您必须执行以下操作:

      export class SessionService {
      private loggedIn: boolean;
      constructor(private router: Router) {
        this.loggedIn = false;
      }
    
      public isLoggedIn(): boolean {
        return this.loggedIn;
      }
    
      public setLoggedIn(value: boolean): void {
        const previous = this.loggedIn;
        this.loggedIn = value;
        if (previous === this.loggedIn) {
          return;
        }
        const i = this.router.config.findIndex(x => x.path === '');
        this.router.config.splice(i, 1);
        this.router.config.push(
          {path: '', loadChildren: () => import('app/handler/handler.module').then(mod => mod.HandlerModule)}
        );
      }
    }
    
    就这样


    如果您想要另一篇参考,这里有一篇文章,其中他们使用了相同的方法:

    这种方法对我来说确实有效,但在提供
    ROUTES
    令牌时,我突然不得不将所有(非惰性)组件添加到
    entryComponents
    数组中。你知道为什么吗?嗨@devqon,当我使用Angular 8时,没有必要将它们添加到
    entryComponents
    ,这是我的回复:你在其他模块中使用这些组件吗?可能是因为我的组件有点不同;有一个“遗留”组件急切地加载到路由中,但现在我想有一个交换机,它将加载整个功能模块。我将深入探讨,但由于sub-routingHi@German Quinteros的其他问题,目前我不得不恢复这种方法。请您为此提供一个stackblitz。添加此解决方案后,我发现路径错误。您好@Mayurkukakadiya,这里有解决方案的Github repo:
    // AppRoutingModule
    
     {
        path: '',
        loadChildren: './handler/handler.module#HandlerModule'
     }
    
      export class SessionService {
      private loggedIn: boolean;
      constructor(private router: Router) {
        this.loggedIn = false;
      }
    
      public isLoggedIn(): boolean {
        return this.loggedIn;
      }
    
      public setLoggedIn(value: boolean): void {
        const previous = this.loggedIn;
        this.loggedIn = value;
        if (previous === this.loggedIn) {
          return;
        }
        const i = this.router.config.findIndex(x => x.path === '');
        this.router.config.splice(i, 1);
        this.router.config.push(
          {path: '', loadChildren: () => import('app/handler/handler.module').then(mod => mod.HandlerModule)}
        );
      }
    }