Скрыть компонент в Angular в определенном динамическом маршруте

Мне нужно скрыть определенные компоненты с моей главной домашней страницы, такие как панель навигации и нижний колонтитул, когда я вхожу в свою панель администратора. Мои административные компоненты лениво загружаются на основе административного модуля при вызове. Необходимые компоненты скрываются, как и ожидалось, при просмотре администратором, если маршруты не являются динамическими, например, /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>

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

Nicholas K 19.12.2020 11:41
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
2 274
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Здесь вам нужно определить регулярные выражения и протестировать их. Или, может быть, вам достаточно проверить функцию 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()

surjendu_dey 19.12.2020 12:31

Технически вы сможете вызвать <div *ngIf = "shouldShowNavBar(url)"> с текущими настройками, которые у вас были.

Some random IT boy 19.12.2020 12:39

при этом он возвращает Невозможно прочитать свойство «включает» из неопределенного. Кажется, url.includes/startsWith приходит как неопределенный

surjendu_dey 19.12.2020 12:48

потому что есть момент, когда url еще не установлен, потому что обратный вызов подписки еще не активирован. Вы должны добавить это в начале функции if (!url) return false;

Some random IT boy 19.12.2020 12:50

Или инициализируйте свойство url некоторым значением, которое имеет для вас смысл.

Some random IT boy 19.12.2020 12:51

внутри какую функцию я должен добавить if (!url) return false; Пожалуйста, дайте немного больше информации, потому что использование асинхронности становится для меня немного сложным

surjendu_dey 19.12.2020 12:54

подход работает, когда внутри [ ] есть только условие . Добавление нескольких URL-адресов, таких как !url.include('/admin/dashboard'), !url.incude('/admin/category/:categoryId'),, не работает.

surjendu_dey 19.12.2020 13:24

замените some на every, если вы хотите выполнить И со всеми условиями. Делайте some, если хотите операционную

Some random IT boy 19.12.2020 15:08

Я вас понимаю... но актуальная проблема все еще остается для динамических маршрутов, таких как /admin/category/:categoryId

surjendu_dey 19.12.2020 15:47

Все ваши динамические маршруты будут начинаться с /admin/category, а затем будут сопровождаться /123 или любым другим идентификатором. Так что с теми, что вы можете просто сделать url.startsWith('/admin/category'), вы сопоставите все пути, которые начинаются с /admin/category. Если у вас есть сложный URL-адрес, я предлагаю использовать регулярные выражения, у вас есть несколько примеров с моим кодом, а также у вас есть ссылка на документацию о том, как их использовать.

Some random IT boy 19.12.2020 16:01

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>

Пожалуйста, объясните свои ответы, чтобы другие могли извлечь из этого пользу.

rcanpahali 15.09.2021 14:09

Другие вопросы по теме