Angular - 显示除url之外的另一条路径

时间:2017-02-15 01:14:37

标签: angular typescript angular2-routing

以下是该方案:

  • /group/
  • 我点击了一个群组,因此尝试转到/group/:id
  • 使用激活的路线调用我的AuthGuard,解析并检查CanActivate
  • CanActivate检测到用户不应该去路线 用户可能在检索组列表之间失去了权利,并且他试图访问特定的列表。

目前的行为是,如果我返回false,则永远不会激活url。如果我返回true,则会激活url,但随后将呈现整个组件树,并且所有router-outlet都需要实际存在。

我想做什么:

应激活网址(即/group/:id位于网址和历史记录中),但显示的网页应与另一条路线相对应(例如/404/login)。 我坚持认为地址栏中的网址必须保持原始/group/:id

我考虑过两种可能性:

  • 拥有本地404组件,并隐藏路由器插座,如果需要,显示404 但问题是404组件应该是全局的,不应该显示从root到url的嵌套模板。它不仅仅是最后一部分无效,而是整条路线。
  • 相反,我可以有一个服务存储有关我们是否应该显示404的信息,然后是一个隐藏路由器插座并在需要时显示404的顶级组件。

尽管如此,这些解决方案对我来说似乎并不完美。他们只是解决问题,而不是实际解决问题 特别是,router-outlet无法*ngIf编辑,这意味着即使我正在显示404或登录页面,DOM也将填充已激活的整个网站组件路由,但没有任何数据,即使用户不应该看到它。这对我来说似乎很难看。 我并没有试图解决路由器出口应该存在以解决路由的问题,我只想要角度来假装网址上的路由,并激活另一个路径。

使用Angular实现此行为的正确方法是什么?

由于

2 个答案:

答案 0 :(得分:0)

我认为这是Angular 2的方法:

a)对于未找到的页面,有回退路径" **"

{
    path: '**',
    component: NotFoundComponent
}

b)对于受保护的页面,有onActivate机制

{
    path: 'private',
    component: PrivateComponent,
    canActivate: [Guard]
}

我认为你不得不隐藏或者不知道路由器插座。路由器插座始终存在,是应用程序的重要组成部分。

Plunkr:

  • 进入窗口模式,以便能够检查地址栏中的路线
  • 点击"导航到非现有页面":地址栏显示" /不存在"但实际上你看到404组件
  • 点击"导航到私人":Guard返回false,这意味着导航被取消。由于在路由器上订阅Observable事件,用户将被重定向到登录页面。 " /登录"就是你在地址栏中看到的。

https://plnkr.co/edit/FSklRhhQV0cpLFP53I13

答案 1 :(得分:0)

使用最新的答案,我挖掘了Router课程,并认为我们可以将{skipLocationChange: true}传递给Router.navigate,以便不更新网址。

因此,当路由被激活时,在组件的构造函数中,我只需要检查路由参数是否已解析为有效对象,如果不是这样,我会默默导航到404:

@Injectable()
export class GroupResolve implements Resolve<Group> {
    constructor() {}

    resolve(route: ActivatedRouteSnapshot) {
        return api.getGroup(route.params['id']);
        /* Returns null if user can't access such a group */
    }
}

@Component({
    templateUrl: 'group.component.html',
    providers: [ GroupResolve ]
})
export class GroupComponent {
    constructor(public route: ActivatedRoute, private router: Router) {
        if(route.snapshot.data['group'] == null) {
            /* The user can't access the given group page, silently navigate to a global 404 route */
            this.router.navigate(["404"], {skipLocationChange: true});
        }
    };
}