Nelle applicazioni Angular, la direttiva NgClass è la di fatto modo per impostare le classi CSS in modo dinamico sugli elementi DOM. Abbiamo imparato tutto sulle sue numerose permutazioni nel Assegnazione di classi dinamiche con NgClass articolo. Oggi esploreremo un uso specifico di NgClass per attivare e disattivare la visibilità di un elemento in base alle interazioni dell’utente. In particolare, lo utilizzeremo per visualizzare un menu a discesa sia sugli schermi touch che su quelli tradizionali.

Il problema definito

Sugli schermi tradizionali, è bello associare la visibilità di un menu a tendina al mouseenter e mouselascia eventi in modo che gli utenti non debbano fare clic sul trigger del menu per visualizzare il menu a discesa. Tuttavia, i touchscreen non supportano gli eventi al passaggio del mouse. In molti casi, convertono gli eventi mouseenter in clic. Questo è un problema perché una volta attivato, l’attivazione dell’evento mouseleave correlato non è un’attività banale.

Una soluzione a questa sfida è sostituire le regole CSS che si basano su :passa il mouse pseudo classe con quelle che includono una classe con una connotazione specifica che denota lo stato aperto del menu. Come vedrai tra poco, può essere qualcosa di semplice come “menu aperto”.

Il risultato finale del tutorial di oggi sarà un menu che, per molti versi, assomiglia al controllo MatMenu di Angular Material. Sebbene sia una buona scelta se hai bisogno di funzionalità più avanzate, se desideri solo una semplice implementazione fai-da-te, l’approccio descritto qui andrà benissimo!

L’elemento scatenante

Piuttosto che creare un nuovo progetto da zero, aggiungeremo semplicemente un collegamento Menu alla MatToolbar che abbiamo creato in un tutorial precedente:

Nel markup HTML di seguito, il DIV contenitore di menu è l’attivatore a discesa. Su eventi clic e invio del mouse, il menuAperto la variabile è impostata su vero; è anche impostato su falso in congedo di topo. Quindi, questo si prende cura dei dispositivi con schermi tradizionali. Per i touchscreen, l’evento clic duplica l’azione del mouseenter per visualizzare il menu a discesa. La chiusura del menu a discesa corrispondente avviene nel gestore dei clic del DIV del menu a discesa:

<mat-toolbar color="primary">
<a [routerLink]="['/']">Home</a>  
<a [routerLink]="['/survey']">Survey</a>  
<div class="menu-container"
	 (click)="menuOpened = true" (mouseenter)="menuOpened = true" (mouseleave)="menuOpened = false">
<span>Menu</span>
<div [ngClass]="{ 'menu-opened': menuOpened }" class="dropdown-menu">
<a *ngFor="let ic of investmentClasses" (click)="onClick($event)">
<mat-icon mat-list-icon>{{ ic.icon }}</mat-icon>
<span class="dropdown-menu-item">{{ ic.text }}</span>
</a>
</div>
</div>
</mat-toolbar>

Il DIV del menu a discesa contiene la direttiva ngClass che aggiunge la classe aperta dal menu ogni volta che menuAperto la variabile valuta vero. Ogni voce di menu è un collegamento il cui clic è legato al onClick($evento) metodo.

Le classi di investimento

Gli elementi dell’elenco vengono generati dinamicamente utilizzando un ciclo ngFor nel modello. Normalmente, questi sarebbero probabilmente forniti da un servizio, ma, per gli scopi di questo tutorial, li troverai nella classe Component. Per rafforzare la coerenza tra gli elementi di investmentClasses, implementa l’interfaccia InvestmentClass:

import { Component } from "@angular/core";


export interface InvestmentClass {
icon: string;
text: string;
value: string,
}


@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
public menuOpened = false;
public investmentClasses: InvestmentClass[] = [
{
icon: "euro_symbol",
text: "currencies",
value: "currency"
},
{
icon: "local_florist",
text: "commodities",
value: "commodity"
},
{
icon: "insert_chart",
text: "indices",
value: "index"
},
{
icon: "business",
text: "stocks",
value: "stock"
}
];


//...
}

Il gestore di eventi onClick()

Considerando che siamo stati in grado di incorporare tutti i gestori di eventi del trigger di menu direttamente nel modello, dovremmo impiegare un gestore di eventi appropriato qui in modo da poter evitare che l’evento si sposti verso il genitore. Senza quel passaggio aggiuntivo, anche l’evento click del trigger di menu si attivava, causando il ripristino della variabile menuOpened su true. Di conseguenza, il menu a discesa non si chiudeva mai! Potremmo fare a meno di questo passaggio spostando il menu DIV al di fuori del DIV del trigger, ma ciò renderebbe più difficile il posizionamento sotto il trigger:

public onClick(event: MouseEvent) {
//prevent event bubbling up to parent
event.stopPropagation();
this.menuOpened = false;
}

Messa in piega

Per impostazione predefinita, la regola del menu a discesa imposta la visualizzazione su “nessuno”. Solo quando la classe aperta dal menu viene aggiunta tramite la direttiva NgClass, la visualizzazione del menu cambia in “flex”. Sovrascrive la regola predefinita grazie alla sua maggiore specificità. Uno z-index di “1” assicura che il menu a discesa sia posizionato sugli elementi vicini:

.menu-container .dropdown-menu {
position: absolute;
display: none;
flex-direction: column;
top: 3.2rem;
width: auto;
word-break: keep-all;
z-index: 1;
background-color: #3b488f;
border: 2px solid gray;
}


.menu-container .dropdown-menu.menu-opened {
display: flex;
}


.menu-container .dropdown-menu a {
text-decoration: none;
display: inline-flex;
cursor: pointer;
align-items: center;
padding: 0 0.8rem;
}


.menu-container .dropdown-menu a:not(:last-child) {
border-bottom: 2px solid gray;
}


.menu-container .dropdown-menu a:hover {
background-color: #a12f42;
}

Conclusione

Nelle applicazioni angolari, è una cattiva pratica impostare i nomi delle classi degli elementi direttamente usando codice come document.getElementById('myElt').classList.add('my-class'). È di gran lunga preferibile lasciare che NgClass faccia la sua magia fornendogli il nome della classe, insieme a una variabile o un’espressione booleana che può valutare.

Source link

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.