Угловой маршрутизатор: именованные розетки, похоже, не работают ни с относительными маршрутами, ни с лениво загруженными модулями.

У меня есть некоторые проблемы с угловым маршрутизатором и именованными розетками. У меня есть список участников, и я хочу отредактировать выбранного участника на той же странице в именованном выходе маршрутизатора. И я хотел бы иметь обработку членов в лениво загруженном модуле.

StackBlitz

Это работает, когда модуль не лениво загружен. Шаблон выглядит так:

<tr *ngFor="let member of members">
...
<a [routerLink]="['/home/member', {outlets: {right: ['memberedit', member._id]}}]"> Edit</a>

И массив маршрутов:

const routes: Routes = [
  {
    path: 'home', component: HomeComponent,
    children: [
      {
        path: 'member', component: MemberComponent,
        children: [
          {
            path: 'memberlist', component: MemberListComponent,
            resolve: { resolvedListData: MemberListResolver },
          },
          {
            path: 'memberedit/:id', component: MemberEditComponent,
            resolve: { resolvedMember: MemberResolver }
            outlet: 'right',
          },
        ]
      },
    ]
  },
  { path: '', redirectTo: '/home', pathMatch: 'full' },
  { path: '**', component: NotFoundComponent }
];

Когда я пытаюсь удалить ссылку на /home/member, чтобы подготовиться к отложенной загрузке, это больше не работает:

Я пробовал с:

<a [routerLink]="[{outlets: {right: ['memberedit', member._id]}}]">Edit</a>

Это не работает, я думаю, это известная ошибка, маршрутизатор создает этот URL-адрес с одной косой чертой после списка участников:

/home/member/memberlist/(right:memberedit/5f39748b88457a30e32e909d)

И я пробовал с:

<a [routerLink]="['../', {outlets: {right: ['memberedit', member._id]}}]"> Edit</a>

Это работает, когда я в первый раз нажимаю на члена. И дает этот URL:

/home/member/(memberlist//right:memberedit/5f39748b88457a30e32e909d)

Во второй раз, когда я нажимаю на другого участника, я получаю эту ошибку:

Error: Two segments cannot have the same outlet name: 'memberedit/5f4227887687e3162d94f5a3' and 'memberedit/5f39748b88457a30e32e909d'.

И URL-адрес:

/home/member/(/(right:memberedit/5f4227887687e3162…f5a3)//right:memberedit/5f39748b88457a30e32e909d)"

Я также пробовал с:

<a [routerLink]="[{outlets: {primary: ['memberlist'], right: ['memberedit', member._id]}}]">Edit</a>
<a [routerLink]="['../', {outlets: {primary: ['memberlist'], right: ['memberedit', member._id]}}]">Edit</a>

Без всякого везения.

Я пробовал с полным путем в лениво загруженном модуле, который не работает.

<a [routerLink]="['/home/member', {outlets: {right: ['memberedit', member._id]}}]"> Edit</a>

Дает:

url: "/home/member/(memberlist//right:memberedit/5f39748b88457a30e32e909d)", urlAfterRedirects: "/home/member"

И я пробовал все вышеперечисленное в модуле с ленивой загрузкой. Любые идеи?


person Peter Heick    schedule 25.08.2020    source источник
comment
Не могли бы вы создать демонстрацию StackBlitz или что-то подобное? Было бы намного проще найти решение   -  person Andrei Gătej    schedule 26.08.2020
comment
Как добраться до маршрута memberlist? Вы пробовали что-то подобное? [routerLink]=['/home/member', { outlets: { primary: 'memberlist' } }], В конце концов, вы можете попробовать использовать Router.navigateByUrl('/home/member/(memberlist)').   -  person Andrei Gătej    schedule 26.08.2020
comment
Список участников достигается с помощью ‹a [routerLink]=['memberlist']›   -  person Peter Heick    schedule 26.08.2020
comment
Было бы проще найти проблему в StackBlitz или что-то в этом роде.   -  person Andrei Gătej    schedule 26.08.2020
comment
StackBlitz: https://angular-ivy-ebjcn2.stackblitz.io   -  person Peter Heick    schedule 27.08.2020
comment
Похоже, это работает с /home/member', { outlets: ..., верно? Есть ли другие проблемы?   -  person Andrei Gătej    schedule 27.08.2020
comment
Да не работает при ленивой загрузке модуля, И относительный маршрут тоже не работает. Я обновил StackBlitz с лениво загруженным модулем   -  person Peter Heick    schedule 27.08.2020
comment
Оно работает!! Спасибо за помощь :-)   -  person Peter Heick    schedule 23.09.2020
comment
Я рад, что смог помочь!   -  person Andrei Gătej    schedule 23.09.2020


Ответы (1)


Он должен работать с отложенным модулем следующим образом:

ленивый член-routing.module

const routes: Routes = [
    // {
    //     path: '', component: LazyMemberComponent,
    //     children: [
            {
                path: 'list', component: ListComponent,
            },
            {
                path: 'edit/:id', component: EditComponent,
                outlet: 'lazyright',
            },
    //     ]
    // },
];

приложение-routing.module.ts

const routes: Routes = [
  {
    path: 'home', component: HomeComponent,
    children: [
      {
        path: 'member', component: MemberComponent,
        children: [
          {
            path: 'list', component: ListComponent,
          },
          {
            path: 'edit/:id', component: EditComponent,
            outlet: 'right'
          }
        ]
      },
      { 
        path: 'lazymember', 
        loadChildren: () => import('./lazy-member/lazy-member.module').then(m => m.LazyMemberModule),
        component: LazyMemberComponent,
      }
    ]
  },
  { path: '', redirectTo: 'home', pathMatch: 'full'}
];

list.component.html

<a [routerLink]="['/home/lazymember', {outlets: {lazyright: ['edit', member.id]}}]">Edit works - No, no longer</a>

демонстрация StackBlitz


Первоначально это не работало с path: '', component: LazyMemberComponent, из-за того, как Angular Router разрешает навигацию. По сути, для каждого потомка UrlSegmentGroup он будет перебирать текущий массив маршрутов и пытаться найти совпадение.

Например, основной UrlSegmentGroup будет выглядеть так:

{
   children: {
     primary: {
      children: {
         lazyright: {
            children: {},
            segments: ['edit', '2']
         },
         primary: {
            children: {},
            segments: ['list'],
         }
      }
      segments: ['home', 'lazymember']
     } 
   },
   segments: []
}

Затем,

  • 'home' сегмент будет соответствовать path: 'home', component: HomeComponent,
  • 'lazymember' сегмент будет соответствовать path: 'lazymember' ...
  • теперь у нас есть lazyright и primary, оба из которых должны найти свое соответствие в текущем массиве маршрутов, который теперь равен [{ path: '', component: LazyMemberComponent, children: [...] }]; по этой причине раньше не работало

Если вы хотите узнать больше о UrlTrees и UrlSegmentGroups, я написал статья об этом.

person Andrei Gătej    schedule 28.08.2020
comment
Спасибо за ваш ответ. Попробую, когда вернусь из отпуска. - person Peter Heick; 04.09.2020