How to reload a page in angular?

Angular: Genindlæs Ruter & Touch-Scrolling

21/06/2023

Rating: 4.38 (8852 votes)
Indholdsfortegnelse

Angular: Genindlæs Ruter & Løs Touch-Scrolling Problemer

Angular er et kraftfuldt framework til at bygge dynamiske webapplikationer. Men som med enhver teknologi kan der opstå specifikke udfordringer, især når det kommer til brugerinteraktion og navigation. To almindelige problemstillinger, som mange Angular-udviklere støder på, er, hvordan man effektivt genindlæser den aktuelle rute, og hvordan man håndterer problemer med touch-scrolling på mobile enheder, især i kombination med Angular Material.

How to reload a page in angular?
Write a function—e.g., reloadCurrentPage. As window is a global object which can be reused directly in Angular components, window.location.reload() reloads the currently active page. window.location.reload(); Solved a similar scenario by using a dummy component and route for reload, which actually does a redirect.

Denne artikel vil dykke ned i begge disse emner og give dig konkrete løsninger og forklaringer, så du kan forbedre brugeroplevelsen i dine Angular-applikationer. Vi vil se på den moderne måde at håndtere rute-genindlæsning på siden Angular version 5.1 og derefter adressere de frustrerende touch-scrolling problemer, der kan opstå med Angular Material komponenter.

Genindlæsning af den Aktuelle Rute i Angular 5.1+

Tidligere versioner af Angular kunne det være en udfordring at genindlæse den aktuelle rute, da routeren standardmæssigt ikke ville genudføre navigationslogikken, hvis man forsøgte at navigere til den samme URL igen. Men med introduktionen af onSameUrlNavigation i Angular 5.1 blev dette betydeligt simplificeret. Denne indstilling giver dig fin kontrol over, hvordan routeren håndterer navigation til den samme URL.

Konfiguration af Routeren

For at aktivere genindlæsning af den aktuelle rute, skal du foretage to primære ændringer i din routerkonfiguration:

  1. Aktiver onSameUrlNavigation: I din AppRoutingModule (eller hvor din rodrouter er konfigureret), skal du tilføje onSameUrlNavigation: 'reload' til RouterModule.forRoot() options. Dette instruerer routeren om at udløse en komplet navigationscyklus, selv når du navigerer til den samme URL.
  2. Opsæt runGuardsAndResolvers: For de specifikke ruter, hvor du ønsker at genindlæsning skal ske, skal du sætte runGuardsAndResolvers: 'always'. Dette sikrer, at alle guards og resolvers, der er tilknyttet ruten, bliver udført igen, hvilket er essentielt for at genindlæse data eller initialisere komponenten på ny.

Eksempel på Router Konfiguration:

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; const routes: Routes = [ // ... dine andre rute definitioner { path: 'invites', component: InviteComponent, children: [ { path: '', loadChildren: './pages/invites/invites.module#InvitesModule' } ], canActivate: [AuthenticationGuard], runGuardsAndResolvers: 'always' // Vigtigt for at genudføre guards/resolvers } // ... ]; @NgModule({ imports: [ RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' // Aktiverer genindlæsning ved samme URL }) ], exports: [RouterModule] }) export class AppRoutingModule { } 

Håndtering i Komponenten

Selvom routerkonfigurationen muliggør genindlæsningen, skal din komponent aktivt reagere på disse ændringer. Den mest almindelige måde at gøre dette på er ved at abonnere på router-events og derefter geninitialisere komponentens tilstand eller genindlæse data.

  • Abonner på Events: I din komponent skal du injicere Router servicen og abonnere på dens events observable.
  • Identificer NavigationEnd: Når en navigationscyklus er fuldført, udsendes en NavigationEnd event. Det er denne event, du skal lytte efter.
  • Geninitialiser Komponent: Når du modtager en NavigationEnd event (og den er for den aktuelle rute), skal du kalde en metode, der nulstiller komponentens interne tilstand, genindlæser data fra API'er eller udfører andre nødvendige opdateringer.
  • Oprydning: Husk at afmelde dit subscription, når komponenten destrueres (i ngOnDestroy), for at undgå memory leaks.

Eksempel på Komponent Implementering:

import { Component, OnInit, OnDestroy } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-invite', templateUrl: './invite.component.html', styleUrls: ['./invite.component.css'] }) export class InviteComponent implements OnInit, OnDestroy { private navigationSubscription: Subscription; constructor(private router: Router) { } ngOnInit(): void { // Abonner på router events ved initialisering this.navigationSubscription = this.router.events.subscribe((event: any) => { if (event instanceof NavigationEnd) { // Tjek om det er den aktuelle rute, der er genindlæst // (Kan være nødvendigt med yderligere logik for at bekræfte, hvis der er flere ruter) this.initializeInvites(); } }); } initializeInvites(): void { console.log('Initialiserer eller genindlæser invite data...'); // Her placeres logikken for at nulstille tilstand og/eller genindlæse data // f.eks. this.loadInvites(); } ngOnDestroy(): void { // Afmeld subscription for at undgå memory leaks if (this.navigationSubscription) { this.navigationSubscription.unsubscribe(); } } // Eksempel på en metode til at genindlæse data loadInvites(): void { // Logik til at hente invites fra en service } } 

Problemer med Touch-Scrolling i Angular Material

Et andet komplekst problem, som mange udviklere støder på, er, når visse Angular Material komponenter, især knapper og tabeller, ikke tillader touch-scrolling på mobile touchskærme. Dette kan være særligt frustrerende, da funktionaliteten ofte virker fint i browserens udviklerværktøjer, men fejler på rigtige enheder.

Hvorfor sker dette?

Problemet opstår ofte på grund af, hvordan touch-events (touchstart, touchmove, touchend) bliver håndteret af browseren og potentielt af Angular Material's egne event-listeners eller CSS-styling. Nogle gange kan en komponent, der forhindrer standard browseradfærd (f.eks. for at implementere egne gestus), utilsigtet blokere for den simple scrolling-funktionalitet.

Dette ses ofte med:

  • mat-icon-button inde i tabeller: Knapper til CRUD-operationer i en tabelkolonne kan forhindre scrolling af selve tabellen på touch-enheder.
  • Kollapsede sidepaneler (SideNav): Når et sidepanel er kollapset til kun at vise ikoner (f.eks. mat-list-item med mat-icon), kan det blive umuligt at scrolle lodret gennem listen på en touchskærm.
  • Responsivt design med begrænset bredde: Komponenter designet til at være responsive, men som indeholder elementer, der overskrider den tilgængelige bredde (f.eks. en række knapper), kan opleve problemer med horisontal scrolling, selvom scrollbar vises.

Løsningsstrategier

Selvom det kan være svært at diagnosticere præcis, hvor fejlen ligger, er her nogle strategier, du kan prøve for at løse disse touch-scrolling problemer:

1. CSS-justeringer

Ofte kan CSS-regler løse problemet. Prøv at tilføje eller justere følgende CSS-egenskaber på de berørte elementer eller deres containere:

  • touch-action: Denne CSS-egenskab styrer, hvordan browseren håndterer berøringsbevægelser. At sætte den til auto eller pan-y (for lodret scrolling) eller pan-x (for horisontal scrolling) kan hjælpe.
/* Anvend på containeren for de elementer, der skal scrolle */ .scrollable-container { touch-action: pan-y; /* Eller pan-x, eller auto */ overflow-x: auto; /* Sikrer horisontal scrollbar */ white-space: nowrap; /* Kan være nødvendigt for horisontal scroll af elementer */ } /* Specifikt for mat-icon-buttons i tabeller */ table .mat-icon-button { /* Overvej at fjerne event listeners eller sætte touch-action her, men vær forsigtig */ } 

2. Undgåelse af preventDefault()

Hvis du har implementeret egne gestus-håndteringer eller bruger biblioteker, der gør det, skal du sikre dig, at event.preventDefault() ikke kaldes unødvendigt på touchmove events, da dette vil stoppe scrolling.

3. Strukturændringer

Nogle gange kan en simpel ændring i HTML-strukturen gøre en forskel. Prøv at wrappe de problematiske elementer (f.eks. mat-icon-button) i en yderligere div, der har de korrekte scrolling-egenskaber sat.

4. Test med specifikke komponenter

Hvis problemet kun opstår med specifikke komponenter som mat-icon-button, kan det være en interaktion mellem Angular Material's egne event-håndteringer og browserens standard scrolling. I sådanne tilfælde kan det være nødvendigt at undersøge Angular Material's kildekode eller rapportere et issue til dem.

Can a responsive button scroll?
Here is a dumbed down version of my responsive button component with the same html and css structure: Blitz. If you use your browser's built in responsive viewer it should scroll just fine. I have even copied the exact code from that blitz into my application and it does not work properly.

5. Fjernelse af Material Direktivet (Testformål)

Som du nævnte, hvis fjernelse af mat-***-button løser problemet, indikerer det stærkt, at det er relateret til Angular Material's direktiver. Dette kan skyldes, at direktiverne tilføjer event listeners, der forstyrrer standard touch-events. En mulig (men ikke ideel) løsning kunne være at bruge almindelige HTML-knapper med tilpasset styling og derefter tilføje Angular Material's udseende via CSS-klasser, hvis det er absolut nødvendigt og den eneste måde at få scrolling til at virke.

Tabel Sammenligning: Standard Scrolling vs. Angular Material Problemer

SituationForventet AdfærdProblem med Angular MaterialMulig Løsning
Horisontal scroll i containerElementer skubbes ud af syne, scrollbar vises, og man kan swipe horisontalt.Scrollbar vises, men swipe-gestus virker ikke.CSS: touch-action: pan-x; på container, overflow-x: auto;. Undgå preventDefault i touch-events.
Lodret scroll i SideNav (kollapset)Man kan scrolle op og ned gennem listen af ikoner.Scrolling er deaktiveret på touchskærme.CSS: touch-action: pan-y; på SideNav-containeren. Tjek for overlappende elementer.
Knapper i Tabel (f.eks. mat-icon-button)Knapper fungerer, og tabellen kan scrolle horisontalt.Knapperne blokerer for horisontal scrolling af tabellen.CSS: touch-action: none; på knapperne (hvis de ikke selv skal scrolle), eller touch-action: auto; på tabellen. Overvej wrapper divs.

Fejlfinding Trin

  1. Isoler Problemet: Opret en minimal, reproducerbar testcase (som din Blitz-eksempel).
  2. Inspektér DOM & CSS: Brug browserens udviklerværktøjer til at undersøge de berørte elementer og deres forældre. Se efter CSS-regler, der kan forhindre scrolling (f.eks. overflow: hidden på forældre, eller specifikke touch-action værdier).
  3. Test Uden Angular Material: Fjern midlertidigt Angular Material-direktiverne for at se, om problemet forsvinder. Hvis det gør, ved du, at det er relateret til Material.
  4. Eksperimenter med touch-action: Prøv forskellige værdier for touch-action på de relevante elementer.
  5. Tjek Angular Material Issues: Søg på GitHub for Angular Material efter lignende rapporterede problemer.

Konklusion

At mestre Angular indebærer at kunne håndtere både de tilsigtede navigationsmønstre og de uforudsete udfordringer, der opstår med brugerinteraktion. Ved at implementere onSameUrlNavigation: 'reload' og runGuardsAndResolvers: 'always' kan du effektivt genindlæse den aktuelle rute og sikre, at dine komponenter altid er opdaterede. Samtidig kan en kombination af CSS-justeringer og en dybere forståelse af event-håndtering hjælpe dig med at overkomme de ofte frustrerende touch-scrolling problemer med Angular Material, hvilket resulterer i en mere robust og brugervenlig applikation på tværs af alle enheder.

Ofte Stillede Spørgsmål (FAQ)

Q1: Hvornår skal jeg bruge onSameUrlNavigation: 'reload'?

Du skal bruge det, når du har brug for at genudføre logik (som guards, resolvers eller komponentinitialisering) på den aktuelle rute, f.eks. efter en brugerhandling, der ikke ændrer URL'en, men kræver en opdatering af data.

Q2: Kan onSameUrlNavigation forårsage performance problemer?

Ja, hvis det bruges ukritisk. Da det udløser en fuld navigationscyklus, kan det være ressourcekrævende. Brug det kun på de ruter, hvor genindlæsning er nødvendig, og optimer din komponentlogik.

Q3: Hvorfor virker scrolling i Chrome DevTools, men ikke på enheden?

Udviklerværktøjer simulerer touch-events, men den faktiske håndtering og de underliggende drivere på enheden kan variere, hvilket afslører problemer, der ikke er synlige i simulationen. CSS-egenskaber som touch-action er især vigtige for reel enhedsadfærd.

Q4: Er der en måde at undgå at abonnere på router events i hver komponent?

Du kan overveje at oprette en centraliseret service eller en base-komponent, der håndterer dette abonnement og derefter udsender en brugerdefineret event eller bruger en RxJS Subject/BehaviorSubject til at informere andre komponenter om nødvendigheden af en geninitialisering.

Q5: Hvad er den bedste praksis for touch-scrolling med Angular Material?

Prioriter at bruge standard CSS-løsninger som touch-action. Hvis det ikke virker, undersøg specifikke komponenters adfærd og overvej simple DOM-strukturændringer. Undgå at overskrive Material's indbyggede funktionalitet unødvendigt.

Hvis du vil læse andre artikler, der ligner Angular: Genindlæs Ruter & Touch-Scrolling, kan du besøge kategorien Teknologi.

Go up