Почему Angular оценивает только первый маршрут? - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть следующие маршруты, которые имеют одинаковый путь. Маршрут активируется на основе логики c в canLoad, но Angular оценивает первый маршрут только с данными A и не переходит go через секунду, если первый отказывает. Я проверил логи c в canLoad, и в этом нет ничего плохого. Возвращает true и false.

const routes: Routes = [
  {
    path: '',
    component: NbAuthComponent,
    children: [
      {
        path: '',
        canLoad: [AuthGuardProviderService],
        data: {provider: 'A'},
        loadChildren: () => import('./xx/auth.module').then(m => m.AuthModule),
      },
      {
        path: '',
        canLoad: [AuthGuardProviderService],
        loadChildren: () => import('./x/auth.module').then(m => m.AuthModule),
      }
    ]
  }
];

CanLoad:

export class AuthGuardProviderService implements CanLoad {

  constructor() {
  }

  canLoad(route: Route): boolean {
    const data = route.data.provider;
    return this.getRoute(data);
  }

  private getRoute(data): boolean {
    const paths = location.href.split('/');
    if (data === 'A') {
      return true;
    } else if (!data) {
      return true;
    }
  }
}

Обновлен вопрос с использованием UrlMatcher:

что вы Вы пытаетесь выполнить sh с помощью этой реализации

Случай пользователя: у меня есть несколько модулей, и я загружаю модуль на основе URL. Например: пользователь A нажимает: localhost/a и модуль загружается.

path: '',
loadChildren: () => import('./a/auth.module').then(m => m.AuthModule)

А если пользователь B нажимает: localhost/b Я хочу загрузить:

path: '',
loadChildren: () => import('./b/auth.module').then(m => m.AuthModule)

Я могу использовать UrlMatcher, но это работает только для первого маршрута.

const matcher = (url: UrlSegment[], providerParam) => {
  const paths = location.href.split('/');
  if ((paths[3] === '' || paths[3] === 'auth') && providerParam === 'win') {
    return {consumed: url};
  } else if (paths[3] !== '') {
    const provider = providers.find(p => paths[3].toLowerCase() === p.shortName);
    return provider && provider.shortName === providerParam ? {consumed: url} : null;
  }
  return null;
};

И модуль отложенной загрузки имеет:

const routes: Routes = [
  {
    path: '',
    component: NbAuthComponent,
    children: [
      {
        path: '',
        component: NbLoginComponent,
      },
      {
        path: 'sign-in',
        component: NbLoginComponent,
      },
      {
        path: 'sign-up',
        component: NbRegisterComponent,
      }
    ],
  },
];

Теперь проблема с этим подходом состоит в том, что он всегда загружает sign-in составная часть. Он всегда набирает path: '', не переходя на другие пути, такие как auth/sign-up

Возможно, стоит упомянуть, что если пользователь нажимает localhost/a, я устанавливаю a как baseHref, поэтому я не могу использовать это как путь. Было бы просто, если бы я не установил его как baseHref. Путь a или b не является частью маршрута.

Это также помогло бы предоставить больше контекста, если бы мы могли видеть вашу реализацию защиты

Я также попытался использовать guard, но это тоже не полезно, поскольку все пути одинаковы '' пустая строка, а Angular маршруты совпадают с первым и не оценивают защиту для остальных.

что данные, которые вы хотите связать с первым маршрутом и как вы планируете его использовать

Цель данных - просто узнать, какой маршрут оценивается.

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

С такими проблемами я всегда нахожу полезным включить трассировку маршрута, чтобы я мог видеть, что делает маршрутизатор Angular, наблюдая за консолью браузера. Больше информации никогда не помешает.

imports: [
    RouterModule.forRoot(
      routes,
      { enableTracing: true } // <-- debugging purposes only!!!
    )
]

Маршрутизатор Angular выполняет итерации по массиву routes, сравнивая значение window.location.href с переменной path для каждого из ваших маршрутов. Как только он находит совпадение, он загружает компонент или модуль, связанный с этим путем. Как вы видели, он не продолжает перебирать массив routes в поисках других возможных совпадений. Если это произойдет, то Angular Маршрутизатор должен будет определить, какая конфигурация маршрута выиграет, что, вероятно, будет слишком специфичным для реализации c для общей обработки c на уровне платформы.

К счастью, команда Angular предоставляет API под названием UrlMatcher , который позволяет разработчику принять это решение. Это вариант, если вы не можете изменить настройку маршрута по какой-либо причине.

По моему мнению, мы всегда должны избегать изменения поведения фреймворка по умолчанию, если это вообще возможно. На высоком уровне, я бы порекомендовал использовать два разных маршрута и использовать logi c в вашей защите для проверки данных A. Если он существует и это то, что ожидает ваше приложение, загрузите модуль по первому маршруту; в противном случае перенаправьте на второй маршрут.

Мы могли бы предоставить более конкретное c решение, если бы знали:

  • какие данные вы хотите связать с первым маршрутом и как вы планируете его использовать
  • что вы пытаетесь выполнить sh с помощью этой реализации (Что-то вроде: когда пользователь переходит к моему приложению, я хочу проверить, аутентифицированы ли они. Если это так, они переходят к первому маршрут; в противном случае они перенаправляются на второй маршрут, чтобы запустить процесс аутентификации)
  • Это также помогло бы предоставить больше контекста, если бы мы могли видеть вашу реализацию защиты

Если вы не Пока вы не найдете ничего полезного, и вы не можете предоставить больше информации, попробуйте взглянуть на этот пост => Три столпа Angular Маршрутизатор - Состояния маршрутизатора и соответствие URL . Более подробно рассказывается о том, как работает маршрутизатор и как он обрабатывает такие вещи, как сегменты Url.

Надеюсь, это поможет!

0 голосов
/ 18 февраля 2020

Angular соответствует только первому. Это не будет продолжаться, даже если ваша охрана не работает. Вы можете посмотреть на что-то, называемое средством сравнения, которое может заменить аргумент пути как один из способов.

https://angular.io/api/router/UrlMatcher

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...