Мне нужно скрыть определенные компоненты с моей главной домашней страницы, такие как панель навигации и нижний колонтитул, когда я вхожу в свою панель администратора. Мои административные компоненты лениво загружаются на основе административного модуля при вызове. Необходимые компоненты скрываются, как и ожидалось, при просмотре администратором, если маршруты не являются динамическими, например, /admin/login, /admin/dashboard и т. д. Но проблема начинается, если маршруты являются динамическими, такими как /admin/category/:categoryId или /admin/user/:userId, и в этих маршрутах необходимые компоненты, такие как панель навигации и нижний колонтитул, не Не прячься. Я получаю динамические идентификаторы маршрутов, используя ActivatedRoute в необходимых компонентах. Ниже приведен метод, который я использую на своей главной странице для чтения маршрутов приложений и соответствующего отображения/скрытия компонентов.
Main.ts
import { Router, NavigationEnd } from '@angular/router';
public url: any;
constructor(private router: Router) {
this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd) {
this.url = event.url;
}
})
}
Основной.html
<div class = "main__container">
<app-navbar
*ngIf = "url !== '/admin' && url !== '/admin/dashboard' && url !== '/admin/post-article' && url !== '/admin/video' && url !== '/admin/login' && url !== '/admin/sign-up' && url !== '/admin/category/:categoryId'">
</app-navbar>
<app-footer
*ngIf = "url !== '/admin' && url !== '/admin/dashboard' && url !== '/admin/category/:categoryId' && url !== '/admin/post-article' && url !== '/admin/video' && url !== '/admin/login' && url !== '/admin/sign-up'">
</app-footer>
</div>



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Здесь вам нужно определить регулярные выражения и протестировать их.
Или, может быть, вам достаточно проверить функцию string#includes(string). Я бы также предложил использовать более реактивный подход (например, rxjs).
В моем шаблоне у меня было бы:
<div class = "main__container">
<app-navbar *ngIf = "canShowNavBar$ | async">
</app-navbar>
<app-footer *ngIf = "canShowFooter$ | async">
</app-footer>
</div>
Где в машинописном файле у меня было бы:
export class YourComponent implements OnInit {
canShowNavBar$: Observable<boolean>;
canShowFooter$: Observable<boolean>;
navigationEvents$: Observable<NavigationEnd>;
constructor(private router: Router){}
ngOnInit() {
// Like this we define the stream of the NavigationEnd events
this.navigationEvents$ = this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
// This one is not really needed but we're giving some hints to the typescript compiler
map(event => event as NavigationEnd)
);
// Here we define the stream of booleans that determine whether to show the component or not on your template.
this.canShowNavBar$ = this.navigationEvents$.pipe(
map(event => this.shouldShowNavBar(event.url))
);
// Because actually you check for the same conditions
this.canShowFooter$ = this.canShowNavBar$;
}
shouldShowNavBar(url: string): boolean {
// And here you should test against regular expressions:
switch(true) {
case //admin/dashboard/.test(url):
case //admin/category/.test(url):
// More cases where you should show the navBar
return true;
default: return false;
}
}
}
Вы можете прочитать больше о регулярных выражениях в JavaScript здесь
Другим подходом к реализации shouldShowNavBar будет использование некоторых предикатов массива, таких как some: Вот так:
shouldShowNavBar(url: string): boolean {
const conditions = [
!url.startsWith('/admin/dashboard'),
!url.includes('/admin/category'),
// More conditions?
];
return conditions.some(isTrue => isTrue);
}
<div class = "main__container">
<app-navbar *ngIf = "shouldDisplayNavBar(url)">
</app-navbar>
<app-footer *ngIf = "shouldDisplayNavBar(url)">
</app-footer>
</div>
shouldShowNavBar(url: string): boolean {
if (!url) {
return false;
}
const conditions = [
!url.startsWith('/admin/dashboard'),
!url.includes('/admin/category'),
// More conditions?
];
return conditions.some(isTrue => isTrue);
}
есть ли способ использовать только метод shouldShowNavBar(url) и исключить асинхронные функции? если да, то как я могу вызвать его в своем шаблоне с помощью *ngIf и как поймать текущий URL-адрес в моем ngOnInit()
Технически вы сможете вызвать <div *ngIf = "shouldShowNavBar(url)"> с текущими настройками, которые у вас были.
при этом он возвращает Невозможно прочитать свойство «включает» из неопределенного. Кажется, url.includes/startsWith приходит как неопределенный
потому что есть момент, когда url еще не установлен, потому что обратный вызов подписки еще не активирован. Вы должны добавить это в начале функции if (!url) return false;
Или инициализируйте свойство url некоторым значением, которое имеет для вас смысл.
внутри какую функцию я должен добавить if (!url) return false; Пожалуйста, дайте немного больше информации, потому что использование асинхронности становится для меня немного сложным
подход работает, когда внутри [ ] есть только условие . Добавление нескольких URL-адресов, таких как !url.include('/admin/dashboard'), !url.incude('/admin/category/:categoryId'),, не работает.
замените some на every, если вы хотите выполнить И со всеми условиями. Делайте some, если хотите операционную
Я вас понимаю... но актуальная проблема все еще остается для динамических маршрутов, таких как /admin/category/:categoryId
Все ваши динамические маршруты будут начинаться с /admin/category, а затем будут сопровождаться /123 или любым другим идентификатором. Так что с теми, что вы можете просто сделать url.startsWith('/admin/category'), вы сопоставите все пути, которые начинаются с /admin/category. Если у вас есть сложный URL-адрес, я предлагаю использовать регулярные выражения, у вас есть несколько примеров с моим кодом, а также у вас есть ссылка на документацию о том, как их использовать.
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'my-component',
templateUrl: './my.component.html',
styleUrls: ['./my.component.scss']
})
export class MyComponent implements OnInit {
constructor(
private router: Router,
) {}
ngOnInit() {
}
/**
* Check if the router url contains the specified route
*
* @param {string} route
* @returns
* @memberof MyComponent
*/
hasRoute(route: string) {
return this.router.url.includes(route);
}
}<!-- First view -->
<div *ngIf = "hasRoute('home')">
First View
</div>
<!-- Second view activated when the route doesn't contain the home route -->
<div *ngIf = "!hasRoute('home')">
Second View
</div>Пожалуйста, объясните свои ответы, чтобы другие могли извлечь из этого пользу.
Ваш ответ может быть улучшен с помощью дополнительной вспомогательной информации. Пожалуйста, отредактируйте , чтобы добавить дополнительные сведения, такие как цитаты или документация, чтобы другие могли подтвердить правильность вашего ответа. Вы можете найти больше информации о том, как писать хорошие ответы в справочном центре.
Попробуйте использовать шаблон регулярного выражения для сопоставления шаблонов, чтобы определить, следует ли скрывать или показывать маршруты, ИЛИ Используйте службу, которая содержит информацию для определения скрытия/отображения и подписки на них в каждом компоненте, которому требуется эта функция.