Я хочу загрузить отдельные компоненты для одинаковых структурированных путей.
Средства :
example.com / what-post-slug -> LoadКомпонент публикации
example.com/whwhat-page-slug -> Загрузка компонента страницы
example.com/hello-i-am-a-string -> Загрузка компонента публикации (поскольку этот слаг относится к записи)
example.com/about-us -> Загрузить компонент страницы (поскольку этот слаг относится к странице)
Зачем мне это делать?
Кто-то может подумать : эй, но почему бы вам просто не определить два префиксных различных пути, для чего существуют пути?
Ответ таков:: Я создаю (кстати, с открытым исходным кодом ) угловую тему WordPress, и я хочу, чтобы маршрутизация была тем, что решит пользователь, без принудительного создания какой-либо жестко заданной структуры.
В одномиз множества возможностей, сообщений и страниц (если вы не знаете WordPress, просто знайте, что это два разных типа контента, которые я хочу использоватьнезависимые Модули и Компоненты для) могут совместно использовать слагов на корневом уровне.
И на первый взгляд, я не могу знать, относится ли слаг к сообщению или странице или к чему-то еще (поэтому UrlMatcher
здесь не может помочь).
Думал ли я о решении?
Да, из трех.
Первое решение
Я мог бы создать компонент Wrapper, который будет загружаться для универсального маршрута, а затем внутри этого компонента сделать что-то вроде:
<whatever-a-component *ngIf="showComponentA()"><whatever-a-component>
<whatever-b-component *ngIf="showComponentB()"></whatever-b-component>
И позволить компоненту Wrapper выполнить всю логику.
Это добавляет дополнительный промежуточный компонент в игру.
Второе решение
Используйте распознаватель для перехвата, а затем выполните всю логику в распознавателе.
Проблема в том, что мне нужно подписаться на http-сообщение, чтобы узнать, с каким типом контента я имею дело, и, поскольку метод Resolver resol () должен возвращать Observable, подписывать там нехорошо.
Конечно, это работает, если яПовторите заполнитель, наблюдаемый некоторое время, например:
// ... inside resolve()
// Force an observable return to allow suscriptions take their time
return Observable.create(observer => {
setTimeout(() => {
console.log("Resolver observable is done");
observer.complete();
}, 15000);
});
... или если я передам свою подписку с mergeMap()
и верну ПУСТО, когда получу результаты от моей подписки.
И как только я получу свои данные обратно, я могу установить новые маршруты, включая текущий путь, который должен указывать на его конкретный компонент.
Это не кажется мне очень чистым подходом.
Третье решение
Просто загрузите обычный компонент Dispatcher, который выполнит все проверки на OnInit()
, а затем перейдите к «секретному» специфичному для компонента URL-адресу, но с использованием { skipLocationChange: true }
, поэтомуУ пользователя будет правильный маршрут, а также будет загружен правильный компонент.
Но, опять же, это добавляет дополнительный промежуточный компонент в игру.
Я думаю, что это самое чистое решение, так как примодуль «Маршрутизация приложений». Я могу сделать что-то вроде:
{
path: 'wp-angular/view-post/:id',
loadChildren: () => import('./view-post/view-post.module').then(m => m.ViewPostModule)
},
{
path: 'wp-angular/view-page/:id',
loadChildren: () => import('./view-page/view-page.module').then(m => m.ViewPageModule)
}
Итак, эти модули будут загружаться с отложенной загрузкой, только если пользователь действительно посетит один из этих двух типов контента.
AКроме того, этот компонент типа контента уже будет доступен, если пользователь затем посетит второй контент того же типа.
И тот факт, что я могу использовать { skipLocationChange: true }
, позволит сохранить путь, как ожидалось.
Кроме того, это позволяет отображать отзывы о загрузке навигации без необходимости подписки на события маршрутизатора.
Вопрос
Что бы вы сделали и почему?
Возможно, мне не хватает какой-то волшебной функции Angular, которая позволяет делать это прямо в точку.