【问题标题】:Different Layout/html structures for different pages in angular 8 Not working角度8中不同页面的不同布局/ html结构不起作用
【发布时间】:2020-06-23 14:48:10
【问题描述】:

我尝试创建公共路由和安全路由,每个路由都具有不同的 html 结构(安全路由将具有仪表板感觉/外观,而公共路由具有更多营销类型的结构),但路由不起作用。我感觉我有太多 <router-outlets> 但我不是 100% 确定。

我的 AppRoutingModule 如下所示:

    const PUBLIC_ROUTES: Routes = [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      { path: 'register', component: RegisterComponent },
      { path: 'login', component: LoginComponent },
      { path: 'request-demo', component: RequestDemoComponent },
      { path: '**', redirectTo: '' }
    ];

    const SECURE_ROUTES: Routes = [
      { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
      { path: 'dashboard', component: DashboardComponent, canActivate: [ LoggedInGuard ] },
      { path: 'u',
        canActivate: [ LoggedInGuard ],
        children: [
          {
            path: ':id',
            component: UserDetailComponent,
            resolve: { user: UserDetailResolver },
            pathMatch: 'full',
          }
        ]
      }
    ];

    const routes: Routes = [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      { path: '', component: PublicLayoutComponent, children: PUBLIC_ROUTES },
      { path: '', component: SecureLayoutComponent, children: SECURE_ROUTES }
    ];

    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
    export class AppRoutingModule { }

app.component.html 只是 <router-outlet></router-outlet>

public-layout.component.html 是:

    <app-header></app-header>
    <router-outlet></router-outlet>

和secure-layout.component.html是:

    <app-header></app-header>
    <router-outlet></router-outlet>

成功登录后,我的登录服务应通过此路由器(使用路由器)将您从公共布局带到安全布局。

    this.router.navigate(["/dashboard"]);

但在登录时,这似乎不起作用,因为我仍在“/”而不是仪表板和控制台中,检查元素,&lt;app-public-layout&gt; 是正在显示的内容。

更新了 login.component.ts 登录功能:

    login() {
        if (this.authService.login(this.loginModel)) {
          this.loginModel.email = "";
          this.loginModel.password = "";
          console.log(
            "Welcome back " + this.authService.currentUser.firstName
          );
          this.router.navigate(["/dashboard"]);
        } else {
          console.log(
            "Email and/or password is incorrect. Please try again."
          );
          this.loginModel = {
            email: "",
            password: ""
          };
        }
      }

login function in auth service (using local user array for dev):

    login(userEmail: IUserLogin): boolean {
        const userExists = this.users.USERS.find(x => x.email === userEmail.email);
        if (userExists) {
          this.currentUser = userExists;
          localStorage.setItem('user', JSON.stringify(userExists));
          return true;
        } else {
          return false;
        }
      }

登录守卫:

    @Injectable()
    export class LoggedInGuard implements CanActivate {

        constructor(protected router: Router, protected auth: AuthService ) {}

         canActivate() {
            if (localStorage.getItem('access_token')) {
                return true;
            }
            // not logged in so redirect to login page
            this.router.navigate(['/']);
            return false;
        }
    }

【问题讨论】:

  • 所以你的问题是,当你登录时,登录服务应该重定向到/dashboard,但它停留在/?即使您在'' 上有重定向?你能显示LoginServiceLoggedInGuard的相关代码吗?
  • 用认证服务登录功能和登录保护更新了主线程
  • 我删除了 LoggedInGuard 以将其排除在外,成功登录后它仍然重定向到 '/' 并且不显示 /dashboard 或仪表板 html 结构

标签: angular


【解决方案1】:

你的问题是你的路由是如何配置的。

归结为问题路线留下以下配置:

const PUBLIC_ROUTES: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'login', component: LoginComponent },
  { path: '**', redirectTo: '' }
];

const SECURE_ROUTES: Routes = [
  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
  { path: 'dashboard', component: DashboardComponent, canActivate: [ LoggedInGuard ] }
];

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '', component: PublicLayoutComponent, children: PUBLIC_ROUTES },
  { path: '', component: SecureLayoutComponent, children: SECURE_ROUTES }
];

当 url 为 / 时,当前路由器将尝试匹配的顶级路由有 3 个。

应该记住,声明路由的顺序很重要。路由器会按顺序检查。

  1. { path: '', redirectTo: 'home', pathMatch: 'full' }

您的示例中的一个问题是路由 'home' 不存在。

此时/home不存在,所以路由器会回退到下一个路由...

  1. { path: '', component: PublicLayoutComponent, children: PUBLIC_ROUTES }

路由器将匹配第一个孩子,并在其中找到另一个redirectTo: 'home'。然后这将回退到'**' 路径,该路径重定向到''。现在这是一条循环路径。我怀疑路由器会识别这一点并停留在 url /。它将呈现PublicLayoutComponent,而无需放入&lt;router-outlet&gt;

  1. { path: '', component: SecureLayoutComponent, children: SECURE_ROUTES }

路由器甚至没有尝试匹配此路径。

修复

'**' 应该从子路由中移出并移到顶级路由中。

顶级路由应该按照从最具体到最一般的顺序声明。

LoggedInGuard 应该移动到顶级路由,以免您在每个子路由上重新声明它。

您还需要确保添加 'home' 路由。

const PUBLIC_ROUTES: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'login', component: LoginComponent }
];

const SECURE_ROUTES: Routes = [
  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
  { path: 'dashboard', component: DashboardComponent }
];

const routes: Routes = [
  { path: '', component: PublicLayoutComponent, children: PUBLIC_ROUTES },
  { path: '', component: SecureLayoutComponent, children: SECURE_ROUTES, canActivate: [ LoggedInGuard ] },
  { path: '**', redirectTo: '' }
];

演示:https://stackblitz.com/edit/angular-xzqvcr

免责声明:我没有浏览路由器的源代码。所以我不能声称知道它是如何解决循环路线的。我的回答是基于我在这种情况下的观察。

【讨论】:

    【解决方案2】:

    您无需将&lt;router-outlet&gt;&lt;/router-outlet&gt; 放在两个组件中。 从两个组件中删除路由器标签并将&lt;router-outlet&gt;&lt;/router-outlet&gt;放在父组件中,例如app.component.ts,如果未登录,则使用公共组件路由作为默认路由。

    【讨论】:

    • 如果我从 public-layout.html 和 secure-layout.html 中取出 router-outlet 并且只在 app.component.html 中有它,那么我的路由都不起作用
    • 是什么让你说&lt;router-outlet&gt; 元素太多了?这就是您设置布局组件的方式。
    • @KurtHamilton,是的,我是这么认为的 :) 但它不起作用,所以我很难发现为什么我登录后仪表板没有显示。
    猜你喜欢
    • 2018-03-13
    • 2015-10-09
    • 2017-03-24
    • 2014-07-19
    • 2014-12-13
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多