【问题标题】:What's the cleanest way to achieve this behavior using Angular Router?使用 Angular Router 实现此行为的最简洁方法是什么?
【发布时间】:2023-02-10 17:03:02
【问题描述】:

目前我有这个简单的应用程序,它在左侧有一个带有项目列表的 sidebav,当您选择其中一个时,在右侧将有 3 个选项卡,它们将显示有关所选项目的不同信息。比方说:信息、评论、图片。

目前,所选项目的 ID 未在 URL 中使用,因此基本上 URL 将始终如下所示:

.../item/information
.../item/reviews
.../item/images

当我在 sidenav 中选择一个项目时,我 next() 将选定的 ID 放入 BehaviorSubject 中,并且在这 3 个组件中的每一个中,我都听 BS.asObservable() 和 switchMap 到每个产品部分的 GET 端点(getInfo、getReiews、 getImages - 这些不是实际的 enpoint 名称,只是一个例子)。

问题是,现在我想在所选产品 ID 的 URL 中也有。所以我的新网址是这样的:

.../item/123/information
.../item/123/reviews
.../item/123/images

我的问题是,实现这一目标的最佳实践/最干净的解决方案是什么?

我在想我可以将我的路由更新为这样的东西

{
  path: ':id/information',
  component: ItemInfo
},
{
  path: ':id/reviews',
  component: ItemReviews
},
{
  path: ':id/images',
  component: ItemImages
},

从 sidenav,现在我没有进入 BS,而是导航到路线 ['item', item.id, 'information'] 等。

在每个组件信息、评论、图像中,我订阅了 activatedRoute.params 并将 itemId 切换映射到 API 获取。

问题是,我不确定这是最干净的方法.如果我将来有 10 个标签怎么办?规格、视频等。我在所有这些中都添加了这个订阅和 switchMap 逻辑吗?

我在想也许我可以有一个包装器组件,我可以从 URL 中读取 id,然后在该组件中为每个选项卡单独的子项,但是我如何将 ID 传递给每个组件并且仍然为每个组件提供单独的 URL?我仍然需要路由然后将信息作为路由器数据传递?没有太大的改进。

提前致谢!

【问题讨论】:

  • 您可能想看一下商店概念——即 ngrx。您可以获得一次数据,然后从商店中选择它。 Ngrx 还提供了路由集成,因此您可以轻松地将其结合起来。 ngrx.io
  • 谢谢。 NgRx 对于这个项目来说是不可能的。而且我只对路由器结构感兴趣,不确定 NgRx 如何适应它。
  • 怎么会?您的 BehaviorSubject 解决方案实际上已经非常接近 NGRX。路由是通过 NGRX 中的路由器存储集成的,一旦你设置好它就非常容易使用 imo。我认为您的路由定义实际上很好,您的问题是关于“问题是,我不确定这是最干净的方法。如果我将来有 10 个选项卡怎么办?规格、视频等。 。我在所有这些中都添加了这个订阅和 switchMap 逻辑吗? - NGRX 会解决这个问题。归根结底,您必须以某种方式获取和管理数据;)

标签: angular architecture angular-router


【解决方案1】:

您可以在“home”中拥有“sidenav”和“tabs”。

为了自动,我们将定义一条路线,例如

const appRoutes: Routes = [
  {
    path: 'item/:id/information',
    component: ComponentOne,
    data:{label:'Information',path:'/information'}
  },
  {
    path: 'item/:id/reviews',
    component: ComponentTwo,
    data:{label:'Reviews',path:'/reviews'}
  },
  {
    path: 'item/:id/images',
    component: ComponentThree,
    data:{label:'Images',path:'/images'}
  },
];

有些人喜欢(抱歉丑陋的 routerLink,我无法使用相对路径)

<aside>
  <ul>
    <li *ngFor="let item of list">
      <a
        routerLinkActive="active"
        [routerLink]="['/item/'+item.id+'/information']"
      >
        {{item.text}}
      </a>
    </li>
  </ul>
</aside>
<nav *ngIf="router.url!='/'">
  <ul class="nav">
    <li class="nav-item" *ngFor="let route of routes">
      <a
        class="nav-link"
        [routerLink]="router.url.split('/').slice(0,3).join('/')+route.path"
        routerLinkActive="active"
      >
        {{route.label}}
      </a>
    </li>
  </ul>
</nav>
<article><router-outlet></router-outlet></article>

不要忘记将路由器作为公共注入

constructor(public router:Router){}

看到,使用“appRoutes”,你唯一需要的是改变“appRoutes”数组以获取更多“tabs”

途中的每个组件

  sub:Subscription;
  constructor(private activeRoute: ActivatedRoute) {}
  ngOnInit() {
    this.sub=this.activeRoute.params.subscribe(params => {
      this.name = params['id'];
    });
  }
  ngOnDestroy(){
    this.sub.unsubscribe()
  }

看到它是询问参数的组件。你不需要使用“主题”

stackblitz

【讨论】:

    猜你喜欢
    • 2017-05-21
    • 1970-01-01
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 2011-04-10
    相关资源
    最近更新 更多