1.0.12 • Published 10 months ago

sat-router v1.0.12

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

SATRouter

Библиотека реализующая собственный механизм маршрутизации, вместо стандартного.

  • Имеет возможность любого уровня вложенности, эта функциональность отсутствует в стандартном Router
  • Работает на основе состояния, представленного в виде обычного массива объектов
  • Состояние может содержит в себе все необходимые для работы приложения
  • Состояние сериализует в адресную строку на основе указанных функций преобразования из/в строку.
  • Состояние можно получать из любого источника
  • Маршруты могут быть динамическими (добавляться/удалятся налету)
  • Поддерживает динамическую загрузку модулей
  • Множество дополнительных вариантов

пример

схема

Исходный код Песочница

Видео

SATRouterModule

Добавляет директивы и сервисы для навигации внутри приложения между представлениями, определенными в приложении. Вы можете импортировать этот NgModule несколько раз, по одному разу, для каждого модуля с отложенной загрузкой.

смотри раздел ISATRouteResolver

@NgModule({
  declarations: [
    //
  ],
  imports: [    
    SATRouterModule.create(
      // Загрузка определённого компонента
      { path: 'root1', component: RootComponent },
      // Динамически загружаемый модуль
      { 
        path: 'root2', 
        loadChildren: () => 
          import('./modules/root2.module').then(_ => _.Root2Module) 
      }
    )
  ],

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

@NgModule({ 
  imports: [    
    SATRouterModule
  ],
  providers: [
    {
      provide: SAT_ROUTE_RESOLVERS, useFactory: (s_files: MainService) =>
      {
        return s_files.files$
          .pipe(
            first(),
            map(fs => [
              { path: '', component: EditorsComponent },
              ...fs.map(f => ({ 
                path: f, 
                component: EditorComponent, 
                alwaysNew: true
                /* так как компонент не меняется, 
                   что бы была анимация указываем флаг alwaysNew */ 
              }))
            ]));

      }, deps: [MainService]
    }
  ]
})

SAT_LINK_PARSE

Токен представляющий функцию преобразования из строки в полное состояние маршрута

providers: [
  {
    provide: SAT_LINK_PARSE,
    useValue: (link: string) =>
    {
      link = /sat-link:([a-z0-9==%_\.\-"]+)/img.exec(link)?.[1] ?? '';

      if (!link) return of<ISATStateNode[]>(
        [0, 1, 2].map(index => ({
          path: 'root1',
          outlet: index.toString(),
          params: { index },
          children: [
            {
              path: 'child1',
              children: [
                { path: 'subChild1', outlet: '0' },
                { path: 'subChild3', outlet: '1' }
              ]
            }
          ]
        }))
      );

      const s = unzip(decodeURIComponent(link));
      return of(JSON.parse(s));
    }
  },

SAT_STATE_STRINGIFY

Токен представляющий функцию преобразования из полного состояния маршрута в строку

providers: [
 {
   provide: SAT_STATE_STRINGIFY,
   useValue: (rs: ISATStateNode[]) =>
   {
     const s = encodeURIComponent(zip(JSON.stringify(rs)));
     return of(`#sat-link:${s}`);
   }
 }

SATRouterService

Сервис для навигации

Перейти по строковой ссылке

navigate('root1/1');

Перейти по состоянию маршрута

navigate([
{
  path: 'root1',
  params: { name: '123' },
  children: [
    {
      path: '1', params: { id: '321' },
      children: [
        { name: 'left', params: { userId: '321' } },
        { name: 'right', params: { userId: '3212' } },
      ]
    }
  ]
},
{
  path: 'root1',
  name: 'rootRight',
  params: ['', 2,],
  children: [
    { name: 'left', params: { admin: true } },
    { name: 'right', params: ['right2', 6] },
  ]
}
])

updateHistoryAsync

Обновление адресной строки браузера

cloneState

Копия маршрута с выделением текущего уровня Служит для модернизации полного маршрута с последующим переходом

const cloned = cloneState(address);
if (!cloned.currentNode) return;
cloned.currentNode.path = newPath;
this.s_router.navigate(cloned.state);

getNode

Получить узел данных маршрута

SATRouterOutletComponent

Контейнер маршрута, который динамически заполняется в зависимости от текущего состояния маршрутизатора.

Каждый контейнер маршрута может иметь уникальное имя, определяемое необязательным атрибутом name.

<sat-router-outlet></sat-router-outlet>
<sat-router-outlet name='left'></sat-router-outlet>
<sat-router-outlet name='right'></sat-router-outlet>

Именованные контейнеры маршрута будут целями маршрута с тем же именем.

Объект ISATStateNode для именованного маршрута имеет свойство outlet для идентификации целевого контейнера маршрута: ts{path: <base-path>, component: <component>, outlet: <target_outlet_name>}

SATRouterLinkActive

Директива для обнаружения активности маршрута

Свойства

Контейнер маршрута

routerOutlet: SATRouterOutletComponent | undefined

Событие активации отслеживаемого маршрута

isActive$: BehaviorSubject<boolean>

Событие активации отслеживаемого маршрута

activated: EventEmitter<string>

Пример использования

<nav mat-tab-nav-bar>
  <a mat-tab-link (click)="onTabClick()" 
     [satRouterLinkActive]="{rout_path}"
     [routerOutlet]="outlet"
     #rl="satRouterLinkActive"
     [active]="rl.isActive$ | async">
    {{tab1_header}}
  </a>

</nav>
<sat-router-outlet #outlet ></sat-router-outlet>

Защитники

canActivate

Проводит проверку можно ли перейти к маршруту

Представлен в виде свойства распознавателя маршрута ISATRouteResolver canActivate и интерфейсом ISATCanActivate может принимать одиночный объект SATCanActivate или массив SATCanActivate[]

canDeactivate

Проводит проверку можно ли покинуть маршрут Представлен в виде свойства распознавателя маршрута ISATRouteResolver canDeactivate и интерфейсом ISATCanDeActivate может принимать одиночный объект SATCanDeActivate или массив SATCanDeActivate[]

Отладка

Предусмотрен режим отладки с показом SATRouterOutletComponent и текущем состоянием маршрута для этого необходимо зарегистрировать провайдер

{ provide: SAT_ROUTE_CONFIGURATION, useValue: { debug: true } }

пример демо режима

Типы

ISATStateNode

interface ISATStateNode
{
  /** Путь маршрута */
  path?: string;
  /** Имя контейнера маршрута */
  outlet?: string;
  /** Дочерние маршруты */
  children?: ISATStateNode[];
  /** Параметры маршрута*/
  params?: any;
}
ts
### ISATRouteResolver
Интерфейс распознавателя части маршрута
```ts
interface ISATRouteResolver
{
  /** Путь маршрута, если есть именованные контейнеры,
   * то они пишутся `{путь}:{outlet}`
   */
  path: string;
  /** Тип компонента */
  component?: Type<any>;
  /** Загрузчик динамического модуля */
  loadChildren?: LoadChildrenCallback;
  /** Перенаправление */
  redirectTo?: string;
  /** Можно ли активировать */
  canActivate?: ISATCanActivate | ISATCanActivate[];
  /** Можно ли деактивировать */
  canDeactivate?: ISATCanDeActivate | ISATCanDeActivate[];
  /** Можно ли выгружать */
  canUnload?: boolean;
  /** Не проверять на изменение компонента */
  alwaysNew?: boolean;
}

ISATCanActivate

Интерфейс имеет одну функцию, функция может быть асинхронной

interface ISATCanActivate
{
  canActivate(state: RoutePath): 
  Observable<boolean> | Promise<boolean> | boolean;
}

Пример:

SATRouterModule.create([
  { path: '', component: Child1Component },  
  { path: 'subChild3:1', component: Child1Sub1Component },
  {
    path: 'subChild4:1', component: Child1Sub2Component,
    canActivate:
    {
      // тут пример асинхронной проверки реализованной через Promise
      canActivate: async (state: RoutePath) =>
      {
        alert(`нельзя перейти в маршрут "subChild4:1"`)
        return false;
      }
    },
    // при неудачной проверке на активацию перейти на маршрут
    redirectTo: 'subChild3:1'
  }
])

ISATCanDeActivate

интерфейс имеет одну функцию, функция может быть асинхронной

interface ISATCanDeActivate
{
  canDeActivate(component: any, state: RoutePath): 
    Observable<boolean> | Promise<boolean> | boolean;
}

пример

SATRouterModule.create([
  { path: '', component: Child1Component },  
  {
    path: 'subChild2:0', component: Child1Sub2Component,
    canDeactivate: {
      // тут пример асинхронной проверки реализованной через Promise
      canDeActivate: async (component: any, state: RoutePath) =>
      {
        alert('нельзя покинуть маршрут "subChild2:0"')
        return false;
      }
    }
  }
])
1.0.12

10 months ago

1.0.11

2 years ago

1.0.10

2 years ago

1.0.9

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago