Attivazione/disattivazione della visibilità degli elementi in Angular
Tempo di lettura: 4 minuti

Il primo articolo che ho scritto riguardava i relativi menu a discesa. La demo presentava tre menu a discesa per la selezione delle automobili. I menu a discesa contenuti Fa, Modelli, e Taglia livelli, così che “Honda” -> “Civico” -> “LS” descriverebbe un veicolo specifico.

Una UX più moderna probabilmente impiegherebbe un menu a discesa multilivello, in modo che ogni selezione apra una nuova foglia. Angular fornisce alcuni controlli per questo scopo, in particolare il MatTree. Tuttavia, per semplici menu a discesa multilivello, è probabilmente eccessivo. In effetti, puoi crearne uno tu stesso usando HTML, JavaScript e alcuni CSS. Nell’articolo di oggi, impareremo come, aggiungendo un livello al menu a discesa che abbiamo di recente trasformato in un componente Angular 11 personalizzato.

I dati

È probabile che, se stai cercando di creare un menu a discesa multilivello, è perché stai lavorando con dati che vanno ad almeno due livelli di profondità. Per quanto riguarda il nostro componente a discesa originale, possiamo aggiungere un altro livello collegando ogni tipo di investimento a uno strumento, una valuta e ciò che hai, cioè indice -> TSX.

Per farlo, aggiorneremo il Elemento del menu interfaccia per includere un array di sottomenu:

export interface MenuItem {
  icon: string;
  text: string;
  value: string;
  subMenu: Array<{
    text: string;
    value: string;
  }>
}

Ora possiamo aggiungere il sottomenu elementi senza incorrere in errori del compilatore:

 public investmentClasses: MenuItem[] = [
   {
     icon: "euro_symbol",
     text: "currencies",
     value: "currency",
     subMenu: [
      { 
        text: 'CAD', 
        value: 'https://ca.finance.yahoo.com/quote/CADUSD=X/' 
      },
      { 
        text: 'USD', 
        value: 'https://ca.finance.yahoo.com/quote/CAD%3DX?p=CAD%3DX' 
      },
      { 
        text: 'BTC', 
        value: 'https://ca.finance.yahoo.com/quote/BTC-CAD/chart?p=BTC-CAD' 
      }
    ]
   },
   {
     icon: "local_florist",
     text: "commodities",
     value: "commodity",
     subMenu: [
       { 
         text: 'Coffee', 
         value: 'https://ca.finance.yahoo.com/quote/KC%3DF/chart?p=KC%3DF' 
       },
       { 
         text: 'Oil', 
         value: 'https://ca.finance.yahoo.com/quote/CL%3DF/chart?p=CL%3DF' 
       },
       { 
         text: 'Natural Gas', 
         value: 'https://ca.finance.yahoo.com/quote/NG%3DF/chart?p=NG%3DF' 
       }
     ]
   },
   {
     icon: "insert_chart",
     text: "indices",
     value: "index",
     subMenu: [
       { 
         text: 'S&P500', 
         value: 'https://ca.finance.yahoo.com/quote/%5EGSPC/chart?p=%5EGSPC' 
       },
       { 
         text: 'TSX', 
         value: 'https://ca.finance.yahoo.com/quote/XIU.TO/chart?p=XIU.TO' 
       },
       { 
         text: 'DOW', 
         value: 'https://ca.finance.yahoo.com/quote/%5EDJI/chart?p=%5EDJI' 
       }
     ]
  },
  {
     icon: "business",
     text: "stocks",
     value: "stock",
     subMenu: [
       { 
         text: 'APPL', 
         value: 'https://ca.finance.yahoo.com/quote/AAPL/chart?p=AAPL' 
       },
       { 
         text: 'TSLA', 
         value: 'https://ca.finance.yahoo.com/quote/TSLA/chart?p=TSLA' 
       },
       { 
         text: 'MSFT', 
         value: 'https://ca.finance.yahoo.com/quote/MSFT/chart?p=MSFT' 
       }
     ]
  }
];

Se provi la demo a questo punto, scoprirai che funziona esattamente come prima, come il sottomenu gli elementi vengono ignorati dall’applicazione. Quindi, modifichiamo il menu a discesa.component.html modello per visualizzarli.

Visualizzazione dei sottomenu in Angular

Dal momento che ogni sottomenu fa parte di una voce di menu, è meglio posizionare il sottomenu *ngFor all’interno del voci del menu‘ racchiudendo il tag . Aiuta anche con il posizionamento del sottomenu elementi sullo schermo. Notare che il al clic anche il gestore deve essere spostato nel sottomenu elemento:

<a *ngFor="let mi of menuItems;let i = index">
  <span class="dropdown-menu-container">
    <mat-icon mat-list-icon>{{ mi.icon }}</mat-icon>
    <span class="dropdown-menu-item">{{ mi.value }}</span>
  </span>
  <div class="submenu-container">
    <span *ngFor="let sub of mi.subMenu;let j = index" class="submenu-item"
      (click)="onClick($event, i, j)"> {{ sub.text }}</span> 
  </div>
</a>

Senza stile aggiuntivo, il nuovo sottomenu gli elementi appariranno tutti alla rinfusa. Il .submenu-container regola posiziona le voci del sottomenu e ne definisce l’aspetto generale, mentre a:hover .submenu-container governa la loro transizione in altezza da 0 a 128 pixel. L’attributo di transizione aggiunge un po’ di animazione al procedimento:

.submenu-container {
  position: absolute;
  left: 160px;
  display: flex;
  height: 0;
  overflow-y: hidden;
  transition: height 0.5s ease-out;
  overflow: hidden;
  flex-direction: column;
  align-items: stretch;
  box-sizing: border-box;
  width: auto;
  word-break: keep-all;
  z-index: 1;
  background-color: #2d3a85;
}

a:hover .submenu-container {
  border: 2px solid gray;
  height: 128px;
  transition: height 0.25s linear;
}

.submenu-item {
  padding: 0.3rem 0.8rem;
}

Notare che la posizione a sinistra di sottomenu items è hardcoded qui perché i dati sono statici. Se fosse dinamico, dovremmo determinare la posizione sinistra in fase di esecuzione.

Finalmente possiamo vedere le voci del sottomenu quando passiamo il mouse su una voce di menu:

Elaborazione degli eventi di clic in Angular

La ragione per cui al clic L’evento ha originariamente emesso l’indice del menu al componente padre è perché è il modo più semplice per accedere agli elementi dell’array. Questo vale anche per le voci del sottomenu, ma ora abbiamo un problema perché il EventEmitter può emettere solo una variabile alla volta. Possiamo avvolgere gli indici di menu e sottomenu in un oggetto per aggirare questa limitazione. Potremmo semplicemente emettere il sottomenu valore ed evita la ricerca extra, ma il Menu a discesaComponente in realtà non ha alcun interesse a presupporre ciò che il genitore intende fare con l’elemento selezionato.

export interface MenuIndex {
  menuIndex: number;
  submenuIndex: number;
}

export class DropdownMenuComponent {
  @Input()  public menuItems: Array<MenuItem> = [];
  @Output() public itemSelected = new EventEmitter<MenuIndex>();

  public onClick(
         event: MouseEvent, 
         menuIndex: number, 
         submenuIndex: number
  ) {
    event.stopPropagation();
    this.itemSelected.emit({
      menuIndex: menuIndex,
      submenuIndex: submenuIndex
    });
  }
}

In casa dei genitori suItemSelected() funzione, possiamo seguire la sottomenu collegamento utilizzando la posizione del documento assegnare() metodo:

public onItemSelected(menuIndex: MenuIndex) {
  document.location.assign(
    this.investmentClasses[menuIndex.menuIndex]
        .subMenu[menuIndex.submenuIndex].value
  );
}

La dimostrazione

Sopra codeandbox.io, troverai la demo con tutto il codice presentato in questo articolo.

Conclusione

In questo articolo abbiamo visto come non tutti i menu a discesa multilivello richiedano il ricorso a complessi controlli angolari del materiale come il MatTree. Per i menu standard, puoi crearne uno tuo usando nient’altro che HTML, JavaScript e alcuni CSS.

Una cosa che manca al nostro menu è l’accessibilità della tastiera. Aggiungeremo questa capacità la prossima volta.

Source link

Di Simone Serra

Web Designer Freelancer Realizzazione Siti Web Serra Simone Realizzo siti web, portali ed e-commerce con focus specifici sull’usabilità, l’impatto grafico, una facile gestione e soprattutto in grado di produrre conversioni visitatore-cliente. Elaboro siti internet, seguendo gli standard Web garantendo la massima compatibilità con tutti i devices. Sviluppo e-commerce personalizzati, multilingua, geolocalizzati per potervi mettere nelle migliori condizioni di vendita. Posiziono il tuo sito su Google per dare maggiore visibilità alla tua attività sui motori di ricerca con SEO di base o avanzato.