在角度路由器中剪掉 url 的不必要部分



我正在制作一个带有登录和注册页面的应用程序。它们都有很多共同点,我想把它们放在一个叫做auth-component的组件中。

组件层次结构为:

app-component
auth-component
login-component
signup-component
other-component

但是由于mypage.com/auth单独不用于任何事情,我宁愿删除该部分,并具有URL:smypage.com/loginmypage.com/signup,中间没有"身份验证"。

目前,我可以想到的方法是:

  1. 将"身份验证"硬编码到登录组件和注册组件中,这与 DRY 背道而驰(尤其是当有两个以上的组件时)

  2. 使用加载身份验证组件的 mypage.com/:keyword,而身份验证组件又包含

    <app-login *ngIf="currentRoute==='login'"></app-login>

    <app-signup *ngIf="currentRoute==='signup'"></app-signup>

我认为这是一个非常丑陋的黑客,因为登录和注册都是现有页面,而不是一些键值对。

我觉得这应该是一个相当普遍的问题,所以应该有一个标准的方法吗?还是我想错了,整个页面的结构应该完全不同?

我很久以前发现了一个类似的问题,没有答案,所以我希望可以发布这个。

auth-component

不需要是路由。您需要做的就是:

let/login 路由到
  1. LoginComponent 和/signup 路由到 SignupComponent
  2. 创建生成所有常见框架内容的身份验证组件。在两个组件不同的位置,放置<ng-content></ng-content>"占位符"。
  3. 在登录组件和注册组件中,您可以在指定内容时使用身份验证组件

登录组件:

<auth-component>
...login-stuff
</auth-component>

登录内容位于定义ng-content的地方。

因此,在多次回到这个问题并进行大量研究和尝试之后,我找到了我认为最"合适"的方法。我想我会把它贴在这里,以防其他人遇到同样的问题。

我之前接受的答案在许多情况下都有效,但很难与动画之类的东西结合起来,我认为它会在每次页面更改时重新加载父级。这也感觉有点不对劲,因为从某种意义上说,父母是每个孩子的一部分。

这个问题可以通过制作自定义序列化程序来解决,这是我的第一个解决方案。它运行良好,但在这种情况下感觉像是黑客攻击,并且可能效果稍差。

我认为更好的方法是在路由器模块中使用自定义匹配器。就我而言,我创建了一个包含路由的auth-routing.module.ts文件。

export const routes: Routes = [
{
matcher: authMatcher,
component: AuthComponent,
children: [
{
path: 'login',
component: LoginComponent,
},
{
path: 'signup',
component: SignupComponent,
},
],
},
];

使用身份验证匹配器函数

const authMatcher = (url: UrlSegment[]) => {
if (url.length > 0) {
const path = url[0].path;
return path === 'login' ||
path === 'signup'
? { consumed: [] }
: null;
}
return null;
};

UrlMatcher 的官方文档不是很全面,但诀窍是返回一个已消耗的空数组,如果未找到匹配项,则返回 null。在这种情况下,角度路由器将相同的 URL 发送给子级,并且不会使用 UrlSegment。这种方法还有一个额外的好处,即如果没有 LoginComponent 或 SignupComponent,authComponent 本身是无法访问的。/auth不需要例外(自定义序列化程序就是这种情况)。

在文档中,整个 url 作为已使用返回,这意味着路由器停在那里,并且不会向子级发送任何内容。在这种情况下,只会显示一个空的身份验证组件。这在那里没有解释,让我困惑了一段时间。

最新更新