首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在没有分层路由的情况下实现主/明细组件?

如何在没有分层路由的情况下实现主/明细组件?
EN

Stack Overflow用户
提问于 2021-08-05 01:15:24
回答 1查看 78关注 0票数 1

我正在尝试一起实现以下几件事。

路径为/items (复数)的索引页。此页面是可滚动的。

在点击个别项目,我想要显示一个详细页,但路线必须是/item/:id (单数)。

有一个后退按钮的详细信息页面。单击时,它应该返回到/items,但应该保持在它左边的相同滚动位置。

我想把它作为一个主要细节来实现。但是我的路由不在层次结构中?

我该怎么处理呢?

我可以做/items and /items/:id (都是复数)

/item and /item/:id (两者均为单数)

但是我想做一个单数和一个复数

路由配置文件

app-routing.ts

代码语言:javascript
复制
{
    path: 'items',
    loadChildren: () => import('./pages/items/items.module').then(m => m.ItemsModule),
    data: { animation: 'Items'}
  },
  {
    path: 'item',
    loadChildren: () => import('./pages/Item/Item.module').then(m => m.ItemModule),
    data: { animation: 'Item', type: 'Item'}
  },

物料工艺路线配置。

代码语言:javascript
复制
[{
  path: ':id',
  component: ItemComponent,
  resolve: {
    item: ItemResolverService
  },
  runGuardsAndResolvers: 'paramsOrQueryParamsChange'
}]
EN

回答 1

Stack Overflow用户

发布于 2021-08-05 01:51:13

您应该创建一个顶级延迟加载路由,如下所示:

代码语言:javascript
复制
{
  path: 'my-items',
  loadChildren: () => import('./pages/my-items/my-items.module').then(m => m.MyItemsModule)
}

然后使用Angular CLI创建一个新的路由模块,如下所示:

代码语言:javascript
复制
ng generate module pages/my-items/my-items --routing=true

这将创建一个包含2个模块文件的路由模块。其中一个模块文件包含my-items路由的子路由。

在这个模块文件中,你应该这样定义你的子路由:

代码语言:javascript
复制
[
  {
    path: 'items',
    component: ItemsComponent
  },
  {
    path: 'item/:id',
    component: ItemComponent
  }
]

您显然需要创建这两个组件(ItemsComponent和ItemComponent),并且它们应该嵌套在使用它们的模块文件夹中。同样,您可以使用Angular CLI来生成这些组件(如果您这样做了,并且它们是按照声明的方式嵌套的,那么它应该自动在正确的模块中声明它们)。

代码语言:javascript
复制
ng generate component path/component-name

代码语言:javascript
复制
ng g c path/component-name

您可以通过以下方式访问这些路由:

代码语言:javascript
复制
/my-items/items

代码语言:javascript
复制
/my-items/item/ITEM_ID

滚动:

要在用户单击后退时保持滚动位置,请执行以下操作:

在主视图中使用:

代码语言:javascript
复制
@ViewChild('scrollableEl ') scrollableEl: ElementRef;

在HTML中,将#scrollableEl添加到scrollable元素中。

现在,您拥有了可滚动元素的句柄。

然后这样做:

代码语言:javascript
复制
ngAfterViewInit(): void {
  const scrollEl: HTMLElement = this.scrollableEl.nativeElement;
  // set last known scroll top value when master view loads
  const strScrollTop: string = sessionStorage.getItem('scrollTop');
  const scrollTop: number = strScrollTop ? parseInt(strScrollTop, 10) : 0;
  scrollEl.scrollTop = scrollTop;
  // keep track of the last known scroll position
  scrollEl.onscroll = () => {
    sessionStorage.setItem('scrollTop', scrollEl.scrollTop);
  };
}

您不需要向详细信息视图中添加任何代码。

这个解决方案基本上跟踪了sessionStorage中最后一个已知的滚动位置。当主组件加载时,它将列表滚动到最后已知的滚动位置。我的代码没有经过测试,所以可能会有一两个错误,但你应该明白这一点。

示例SETINTERVAL根据注释的巧妙代码

如果您的scroll元素在页面加载时没有准备好,这是一些示例代码,用于在元素准备就绪时抓取该元素。它总是尽可能快地清除间隔。您将需要定制此代码以满足您的需求。

代码语言:javascript
复制
@ViewChild('summaries') summaries: ElementRef;

ngAfterViewInit(): void {
  this.doScroll();
}

@HostListener('window:resize')
onResize(): void {
  this.doScroll();
}

private doScroll(): void {
  this.whenElementReady('summaries').then((el: HTMLElement) => {
    if (el) {
      // change this to the scrollTop value that you need
      el.scrollTop = 0;
    }
  });
}

private whenElementReady(elementName: string): Promise<HTMLElement> {
  return new Promise((resolve) => {
  // will keep trying for 30 seconds
    const maxAttempts = 300;
    let attempts = 0;
    const interval = setInterval(() => {
      const el: HTMLElement = this[elementName]?.nativeElement;
      if (el) {
        clearInterval(interval);
        resolve(el);
      } else if (attempts > maxAttempts) {
        clearInterval(interval);
        resolve(null);
      }
      attempts++;
    }, 100);
  });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68659523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档