How to add angular material component to angular application?

Effektive Menuer med Angular Material

03/04/2022

Rating: 4.71 (10875 votes)

I den moderne webudvikling er en intuitiv og responsiv brugerflade afgørende for en god brugeroplevelse. Angular, et populært framework for at bygge dynamiske webapplikationer, tilbyder sammen med Angular Material en kraftfuld suite af UI-komponenter, der kan forvandle dine applikationer. Blandt disse komponenter er menuerne en fundamental del af navigationen og interaktionen. Denne artikel vil guide dig gennem implementeringen af smukke og funktionelle menuer i Angular ved hjælp af Angular Material, og dækker alt fra grundlæggende opsætning til avancerede funktioner.

How to implement menu items in angular?
To implement menu items in Angular we can use angular material menu module called MatMenuModule. mat-menu selector is used to display floating menu panel containing list of menu items. How to create Nested Menus or sub-menus? How to open mat menu programmatically? How to disable mat-menu-item ? Steps to implement Menu items in Angular applications.

Angular Material er et UI-komponentbibliotek udviklet af Google, der gør det muligt for Angular-udviklere at skabe moderne applikationer på en struktureret og responsiv måde. Ved at bruge dette bibliotek kan vi markant forbedre slutbrugernes brugeroplevelsen, og dermed øge vores applikations popularitet. Biblioteket indeholder moderne, klar-til-brug-elementer, der direkte kan anvendes med minimal eller ingen ekstra kode.

Indholdsfortegnelse

Installation af Angular Material i dit Projekt

Før vi kan begynde at implementere menuer, skal Angular Material installeres i dit Angular-projekt. Forudsætningen er, at du har Angular CLI installeret på dit system.

Trin 1: Tilføj Angular Material

Åbn din terminal i roden af dit Angular-projekt, og udfør følgende kommando:

ng add @angular/material

Denne kommando vil installere biblioteket og konfigurere dit projekt med de nødvendige stilarter og temaer. Du vil blive bedt om at vælge et tema og om at inkludere Angular Material-typografi og browseranimationer. Vælg de indstillinger, der passer bedst til dit projekt.

Trin 2: Importér de Nødvendige Moduler

For at bruge menukomponenten skal vi importere MatMenuModule. Hvis du også ønsker at bruge ikoner, skal du importere MatIconModule. Disse moduler skal importeres i din app.module.ts fil eller i en fælles Material-modulfil, som kan bruges på tværs af applikationen.

import { MatMenuModule } from '@angular/material/menu'; import { MatIconModule } from '@angular/material/icon'; // Kun hvis du vil bruge ikoner

Tilføj derefter de importerede moduler til imports-arrayet i din @NgModule-dekoration:

@NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, BrowserAnimationsModule, MatMenuModule, MatIconModule // Kun hvis du vil bruge ikoner ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }

Grundlæggende Implementering af Angular Material Menuer

Kernen i at skabe en menu i Angular Material er brugen af <mat-menu>-komponenten og direktivet matMenuTriggerFor. En mat-menu er en flydende panel, der indeholder en liste af menupunkter.

Trin 1: Definer din Menu

Brug <mat-menu>-vælgeren til at definere din menupanel. Du skal tilføje en skabelonreferencevariabel (f.eks. #menu="matMenu") til <mat-menu>, som vil blive brugt til at referere til menupanelet.

<mat-menu #menu="matMenu"> <button mat-menu-item>Menupunkt 1</button> <button mat-menu-item>Menupunkt 2</button> </mat-menu>

Inden i <mat-menu> definerer du de enkelte menupunkter ved hjælp af <button mat-menu-item>. Det er vigtigt at tilføje mat-menu-item attributten til dine menuindstillinger, typisk på et <button>-element.

Trin 2: Tilknyt Menuen til en Udløser

<mat-menu>-elementet i sig selv render ikke noget i UI'en. Menuen skal tilknyttes et udløserelement, som vil åbne og lukke menuen. Dette gøres ved hjælp af matMenuTriggerFor-direktivet.

<button mat-button [matMenuTriggerFor]="menu">Simpel Menu</button> <mat-menu #menu="matMenu"> <button mat-menu-item>Menupunkt A</button> <button mat-menu-item>Menupunkt B</button> </mat-menu>

I eksemplet ovenfor tilknytter vi <mat-menu>-containeren til en knap kaldet "Simpel Menu" via matMenuTriggerFor-attributten. Den skabelonreferencevariabel, vi oprettede (#menu), bruges her til at linke udløseren til det korrekte menupanel.

Tilpasning af Menuens Placering

Som standard vises Angular Material-menuen under udløserelementet. Du kan ændre menuens position ved hjælp af xPosition og yPosition egenskaberne på <mat-menu>-vælgeren.

Horisontal Placering (xPosition)

xPosition-egenskaben ændrer menuens position langs den horisontale akse. Den accepterer værdierne "before" eller "after".

<button mat-button [matMenuTriggerFor]="beforeMenu">Før</button> <mat-menu #beforeMenu="matMenu" xPosition="before"> <button mat-menu-item>Element 1</button> <button mat-menu-item>Element 2</button> </mat-menu> <button mat-button [matMenuTriggerFor]="afterMenu">Efter</button> <mat-menu #afterMenu="matMenu" xPosition="after"> <button mat-menu-item>Element 1</button> <button mat-menu-item>Element 2</button> </mat-menu>

Vertikal Placering (yPosition)

yPosition-egenskaben bruges til at ændre menuens position langs den vertikale akse. Den accepterer værdierne "above" eller "below".

<button mat-button [matMenuTriggerFor]="aboveMenu">Over</button> <mat-menu #aboveMenu="matMenu" yPosition="above"> <button mat-menu-item>Element A</button> <button mat-menu-item>Element B</button> </mat-menu> <button mat-button [matMenuTriggerFor]="belowMenu">Under</button> <mat-menu #belowMenu="matMenu" yPosition="below"> <button mat-menu-item>Element A</button> <button mat-menu-item>Element B</button> </mat-menu>

Her er en oversigt over positioneringsmulighederne:

EgenskabVærdierBeskrivelse
xPosition"before", "after"Placerer menuen til venstre (før) eller højre (efter) udløseren.
yPosition"above", "below"Placerer menuen over eller under udløseren.

Menupunkter med Ikoner

Du kan forbedre menupunkternes visuelle appel ved at tilføje Material Design-ikoner. Dette gøres ved at placere <mat-icon>-elementer før menupunktets tekst.

<button mat-button [matMenuTriggerFor]="menuMedIkon">Menu med Ikon</button> <mat-menu #menuMedIkon="matMenu"> <button mat-menu-item><mat-icon>home</mat-icon><span>Hjem</span></button> <button mat-menu-item><mat-icon>info</mat-icon><span>Om os</span></button> </mat-menu>

Du kan også bruge et ikon som selve menupunktets udløser:

<button mat-icon-button [matMenuTriggerFor]="ikonMenu"> <mat-icon>more_vert</mat-icon> </button> <mat-menu #ikonMenu="matMenu"> <button mat-menu-item><mat-icon>settings</mat-icon><span>Indstillinger</span></button> <button mat-menu-item><mat-icon>logout</mat-icon><span>Log ud</span></button> </mat-menu>

Indlejrede Menuer (Submenuer)

At skabe indlejrede menuer, ofte kaldet submenuer, er utroligt simpelt med Angular Material. Du skal blot tilknytte en anden <mat-menu> til et eksisterende <button mat-menu-item> ved hjælp af matMenuTriggerFor-egenskaben.

Lad os opbygge et eksempel med programmeringssprog, der har flere niveauer af submenuer:

<mat-card> <button mat-button [matMenuTriggerFor]="sprogMenu">Sprog</button> <!-- Første niveau Menu --> <mat-menu #sprogMenu="matMenu"> <button mat-menu-item [matMenuTriggerFor]="frontendMenu">Frontend</button> <button mat-menu-item [matMenuTriggerFor]="backendMenu">Backend</button> </mat-menu> <!-- Andet niveau sub-menu: Frontend --> <mat-menu #frontendMenu="matMenu"> <button mat-menu-item [matMenuTriggerFor]="javascriptMenu">Javascript</button> <button mat-menu-item>Typescript</button> <button mat-menu-item>Angular</button> </mat-menu> <!-- Andet niveau sub-menu: Backend --> <mat-menu #backendMenu="matMenu"> <button mat-menu-item>C#</button> <button mat-menu-item>Java</button> </mat-menu> <!-- Tredje niveau sub-menu: Javascript --> <mat-menu #javascriptMenu="matMenu"> <button mat-menu-item>jQuery</button> <button mat-menu-item>VueJs</button> </mat-menu> </mat-card>

Som du kan se, er princippet at ethvert mat-menu-item kan fungere som en udløser for en ny mat-menu, hvilket skaber en hierarkisk struktur. Dette giver mulighed for at skabe komplekse og velorganiserede navigationsstrukturer, som er essentielle for mange applikationer.

Programmatisk Åbning af Menuer

I visse situationer kan det være nødvendigt at åbne en menu programmatisk i stedet for via et brugerklik på en udløser. Dette er muligt ved at få en instans af MatMenuTrigger.

How do I detect a device/platform using angular?
You could write your own Angular service to do this, but the simple solution is to use a library such as ngx-device-detector. It provides a service (which uses navigator.userAgent under the hood) which you can inject into your components to detect what device/platform the user is running. You can use it in your component like:

Trin 1: Få en Reference til MatMenuTrigger

Tilføj en skabelonvariabel (f.eks. #triggerBtn) til det element, der fungerer som din menuudløser. Brug derefter @ViewChild i din komponent-TS-fil til at hente instansen af MatMenuTrigger.

<button mat-button (click)="åbnMenuProgrammatisk()">Åbn Menu</button> <button mat-icon-button #triggerBtn [matMenuTriggerFor]="normalMenu"> <mat-icon>more_vert</mat-icon> </button> <mat-menu #normalMenu="matMenu"> <button mat-menu-item>Hjem</button> <button mat-menu-item>Kontakt</button> </mat-menu>

Trin 2: Åbn Menuen i din Komponent

I din komponentens TypeScript-fil:

import { Component, ViewChild } from '@angular/core'; import { MatMenuTrigger } from '@angular/material/menu'; @Component({ selector: 'app-my-component', templateUrl: './my-component.html' }) export class MyComponent { @ViewChild(MatMenuTrigger) triggerBtn!: MatMenuTrigger; åbnMenuProgrammatisk() { this.triggerBtn.openMenu(); } }

MatMenuTrigger eksponerer flere metoder, herunder openMenu(), som åbner menuen.

Oprettelse af Dynamiske Menupunkter

I mange virkelige applikationer er menupunkter ikke statiske, men genereres dynamisk, f.eks. fra en API eller en observerbar kilde. Du kan nemt oprette dynamiske menuer ved at binde en liste af objekter til <mat-menu-item> ved hjælp af *ngFor.

Trin 1: Definer din Data Struktur

Opret en TypeScript-klasse eller interface, der repræsenterer strukturen for dine menupunkter:

export class MatMenuListItem { menuLinkText!: string; menuIcon!: string; isDisabled!: boolean; routerLink?: string; // Valgfri, til navigation }

Udfyld derefter en array med disse objekter i din komponent:

menuListItems: MatMenuListItem[] = [ {menuLinkText: 'Indstillinger', menuIcon: 'settings', isDisabled: false, routerLink: '/settings'}, {menuLinkText: 'Om os', menuIcon: 'people', isDisabled: false, routerLink: '/about'}, {menuLinkText: 'Hjælp', menuIcon: 'help', isDisabled: false, routerLink: '/help'}, {menuLinkText: 'Kontakt', menuIcon: 'contact_support', isDisabled: true, routerLink: '/contact'} ];

Trin 2: Generer Menupunkter med *ngFor

Brug *ngFor i din HTML-skabelon til at iterere over menuListItems-arrayet og generere menupunkter:

<mat-toolbar> <button mat-icon-button [matMenuTriggerFor]="dynamiskMenu"> <mat-icon>more_vert</mat-icon> </button> <span>Valgt menu: {{selectedMenu}}</span> </mat-toolbar> <mat-menu #dynamiskMenu="matMenu"> <button mat-menu-item *ngFor="let item of menuListItems" (click)="klikPåMenupunkt(item)" [disabled]="item.isDisabled" [routerLink]="item.routerLink" > <mat-icon>{{ item.menuIcon }}</mat-icon> <span> {{ item.menuLinkText }}</span> </button> </mat-menu>

Håndtering af Klikbegivenheder og Navigation

Når en bruger klikker på et menupunkt, vil du ofte udføre en handling eller navigere til en anden rute. Angular Material menuer understøtter standard klikbegivenheder.

Klikbegivenheder

Du kan binde en metode til (click)-begivenheden på <button mat-menu-item>:

// I din komponentens TypeScript-fil kliPaaMenupunkt(menuItem: MatMenuListItem) { console.log(menuItem); this.selectedMenu = menuItem.menuLinkText; // Udfør andre handlinger her }

Angular Rute Navigation

Hvis dine menupunkter skal navigere til Angular-ruter, har du et par muligheder:

  1. Programmatisk Navigation: Brug Angulars Router-service til at navigere baseret på menupunktets data.
  2. import { Router } from '@angular/router'; // ... constructor(private router: Router) {} kliPaaMenupunkt(menuItem: MatMenuListItem) { this.selectedMenu = menuItem.menuLinkText; if (menuItem.routerLink) { this.router.navigate([menuItem.routerLink]); } }
  3. Deklarativ Navigation med routerLink: Hvis menupunktet udelukkende bruges til rutenavigation, kan du direkte tilføje routerLink-attributten til <button mat-menu-item>.
  4. <button mat-menu-item *ngFor="let item of menuListItems" [routerLink]="item.routerLink"> <mat-icon>{{ item.menuIcon }}</mat-icon> <span> {{ item.menuLinkText }}</span> </button>

Deaktivering af Menupunkter

Det er ofte nødvendigt at deaktivere visse menupunkter baseret på brugerrettigheder eller applikationens tilstand. Du kan nemt deaktivere et <mat-menu-item> ved at bruge [disabled]-egenskaben.

Hvis du bruger dynamiske menupunkter, kan du inkludere en isDisabled-egenskap i din dataobjekt og binde den til [disabled]:

<button mat-menu-item *ngFor="let item of menuListItems" (click)="kliPaaMenupunkt(item)" [disabled]="item.isDisabled"> <mat-icon>{{ item.menuIcon }}</mat-icon> <span> {{ item.menuLinkText }}</span> </button>

Husk, at hvis alle menupunkter er deaktiverede, er det ofte bedre at skjule eller deaktivere selve menuudløseren for at undgå en dårlig brugeroplevelse.

Overførsel af Data til Menuindholdspanelet

En avanceret funktion er muligheden for at sende data fra udløserelementet til menuens indholdspanel. Dette giver dig mulighed for at genbruge en enkelt menuinstans med forskellige datasæt, afhængigt af den data, der sendes af udløserelementet. Dette er især nyttigt i scenarier, hvor du har dynamisk indhold, der skal vises i menuen baseret på konteksten.

Brug af matMenuTriggerData og matMenuContent

Du passerer data til menupanelet via matMenuTriggerData inputtet på udløseren. I menupanelet bruges <ng-template matMenuContent> til at modtage og gengive dataen.

Lad os forestille os et scenarie, hvor du administrerer flere brugerkonti, og menuen skal vise kontooplysninger dynamisk:

Komponentens TypeScript-fil (.ts):

export class User { Name!: string; IsActive!: boolean; } export class MenuData { Users!: User[]; OtherMenus!: string[]; ActiveUser!: User; } @Component({ selector: 'app-my-component', templateUrl: './my-component.html' }) export class MyComponent implements OnInit { activeUser: User = { Name: "@angular_js", IsActive: true }; menuItems: MenuData = { Users: [ { Name: "@arungudelli", IsActive: false }, { Name: "@angular_js", IsActive: true } ], OtherMenus: [ "Tilføj eksisterende konto", "Administrer konti" ], ActiveUser: this.activeUser }; constructor() { } ngOnInit(): void { } }

HTML-skabelon (.html):

<button mat-button [matMenuTriggerFor]="administrerKonti" [matMenuTriggerData]="menuItems"> {{activeUser.Name}} </button> <mat-menu #administrerKonti="matMenu"> <ng-template matMenuContent let-data="menuItems"> <ng-container *ngFor="let user of data.Users"> <button mat-menu-item> <span>{{user.Name}}</span> <mat-icon *ngIf="user.IsActive">how_to_reg</mat-icon> </button> </ng-container> <ng-container *ngFor="let othermenu of data.OtherMenus"> <button mat-menu-item>{{othermenu}}</button> </ng-container> <button mat-menu-item>Log af {{data.ActiveUser.Name}}</button> </ng-template> </mat-menu>

I dette eksempel bruges [matMenuTriggerData]="menuItems" til at sende hele menuItems-objektet til menupanelet. Inde i <ng-template matMenuContent let-data="menuItems"> kan vi derefter tilgå disse data via den lokale variabel data. Dette giver en utrolig fleksibilitet til at skabe kontekstafhængige menuer.

Hvis du har et simpelt objekt, kan du direkte bruge let-nøgleordet til at definere en ny variabel og bruge den i menuindholdspanelet:

<button mat-icon-button [matMenuTriggerFor]="brugerMenu" [matMenuTriggerData]="{navn: 'ArunGudelli'}"> <mat-icon>more_vert</mat-icon> </button> <mat-menu #brugerMenu="matMenu"> <ng-template matMenuContent let-brugernavn="navn"> <button mat-menu-item>Log af {{brugernavn}}</button> </ng-template> </mat-menu>

Vigtig Bemærkning: Ingen MenuItemCheckbox/MenuItemRadio Roller

Det er vigtigt at bemærke, at Angular Material ikke understøttermenuitemcheckbox eller menuitemradio roller. Dette betyder, at du ikke direkte kan implementere menupunkter, der fungerer som afkrydsningsfelter eller radioknapper med indbygget ARIA-support via Angular Material's menukomponent. Hvis du har brug for denne funktionalitet, skal du sandsynligvis implementere det manuelt med din egen logik og styling, eller overveje alternative komponenter.

Ved åbning fokuserer udløseren det første fokuserbare menupunkt. Ved lukning returnerer menuen fokus til sin udløser. Undgå at oprette en menu, hvor alle punkter er deaktiverede; skjul i stedet eller deaktiver menuudløseren.

Ofte Stillede Spørgsmål om Angular Material Menuer

Hvordan forhindrer jeg, at en menu lukker, når jeg klikker på et menupunkt?

Som standard lukker en Angular Material menu, når du klikker på et mat-menu-item. Hvis du vil forhindre dette for specifikke punkter (f.eks. for at lade en bruger vælge flere indstillinger), kan du stoppe event-propagationen. Dette er dog en avanceret brugssituation og kræver manuel håndtering af menuens tilstand.

Kan jeg style menuerne med mit eget CSS?

Ja, Angular Material-komponenter kan styles. Du kan bruge standard CSS til at overskrive Angular Materials indbyggede stilarter. Det anbefales at bruge CSS custom properties (variabler) leveret af Angular Material, eller at anvende ::ng-deep eller en global stilarkfil for at målrette specifikke elementer, da komponenterne bruger Shadow DOM.

Er der nogen tilgængelighedsovervejelser for menuer?

Angular Material er designet med tilgængelighed i tankerne og følger ARIA-best practices. Menuer håndterer automatisk fokusstyring (flytter fokus til det første menupunkt ved åbning og tilbage til udløseren ved lukning) og tastaturnavigation (piletaster til at navigere, Enter/Space til at vælge). Sørg for at dine egne implementeringer ikke bryder disse indbyggede funktioner, og at tekstindhold er klart.

Hvordan integrerer jeg menuer med Angular Forms?

Mens mat-menu primært er til navigation og simple handlinger, kan du placere formkontroller inde i menupunkter. Men hvis du har komplekse formularer, der kræver input og validering, er det ofte bedre at bruge en dialog (MatDialog) eller et sidepanel (MatSidenav) for en bedre brugeroplevelse.

Konklusion

Angular Material tilbyder en robust og fleksibel måde at implementere menuer på, der spænder fra simple drop-downs til komplekse, indlejrede navigationsstrukturer. Med funktioner som dynamiske menuer, programmatisk kontrol og muligheden for at overføre data, kan du skabe enestående og responsive brugergrænseflader. Ved at følge de retningslinjer, der er beskrevet i denne artikel, kan du udnytte det fulde potentiale af Angular Material menuer og levere en intuitiv og engagerende brugeroplevelse i dine Angular-applikationer.

Hvis du vil læse andre artikler, der ligner Effektive Menuer med Angular Material, kan du besøge kategorien Teknologi.

Go up