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

问题描述 投票:1回答:1

[如果您碰巧是Facebook用户,您可能会注意到用户登录或注销时,Url“ https://www.facebook.com”不会更改。我在构建的应用程序中遇到了相同的问题(使用角度5)。尽管有一些建议的解决方案:

  1. [首先是使用相同的路径,使用一个组件(例如:home),然后在home的模板内部,使用* ngIf插入in,out(组件),在运行时我们会根据用户的身份登录或注销用户关于这一点,我们显示相应的(输入或输出)组件。

home.component.html

<app-in *ngIf="loggedIn"></app-in>
<app-out *ngIf="!loggedIn"></app-out>
  1. 我认为会更干净的第二种方法,特别是在使用lazy loading时,是先让两条路由具有相同的空路径,然后用matcher保护(例如:第一个) ,现在说实话,这仍然很丑陋,因为匹配器不适合用于这种高级用法(它也同步并且没有包装在服务中,例如canLoadcanActivate .. etc-,其中可以轻松注入一些其他服务(例如:authService)以检查是否已登录或注销)。

home.routing.ts

.
.
.

const routes: Routes = [
  {
    matcher: matcherFunc,
    loadChildren: './in/in.module#InModule'
  },
  {
    path: '',
    loadChildren: './out/out.module#OutModule'
  }
];

.
.
.

这是匹配器功能:

export function matcherFunc(url: UrlSegment[]) {
  let currentUser;


    currentUser = localStorage.getItem('user');

  if (url.length === 0 && currentUser) {
    return ({ consumed: url });
  } else {
    return null;
  }
}

当我将应用程序升级为universal时,问题变得更加严重,因为在这种情况下,我必须在我所在的服务器端上处理全局变量(窗口,localStorage..etc)。完全被困!

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

angular angular5 serverside-rendering angular-universal
1个回答
0
投票

您可以使用通过使用Angular的useFactory提供程序提供RouterModule的ROUTES来处理应该加载哪个模块的模块。

代码可能是类似的东西。

// 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,因为应用程序将仅加载首次加载的页面(模块)。这是因为HandlerModule中useFactory提供程序使用的函数“ configHandlerRoutes”仅在我们第一次导航到“”路径时才执行,之后Angular Router已经知道他必须加载哪个模块。

最后在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)}
    );
  }
}

就是这样。

如果您要再参考,这里是一篇文章,他们使用相同的方法:https://medium.com/@german.quinteros/angular-use-the-same-route-path-for-different-modules-or-components-11db75cac455

© www.soinside.com 2019 - 2024. All rights reserved.