Angular UI Routing and Components

Angular UI Router har langsomt integreret understøttelse af routing til Angular-komponenter. Dette indlæg vil diskutere, hvorfor det er nyttigt, og hvordan man gør det ved hjælp af både Angular UI Router 0.x.x og 1.0.0.0-beta.x-versionerne.

Baggrund

Med indførelsen af Angular-komponenter i version 1.5 blev konceptet med et enkeltstående, genanvendeligt sæt af adfærd og visninger lettere at definere end tidligere gjort i direktiver. Disse ændringer omfatter: abstraktion af omfang, eksplicit binding til controllere, tilvejebringelse af livscykluskroge i controlleren samt et par andre ting.

Dette gav mulighed for bedre komponentisering af hele visninger og applikationer. Dermed kom erkendelsen af, at en webside er en komponent, der består af komponenter.

Det sagt, blev routing til en komponent en ønsket adfærd.

Smarte vs. dumme komponenter

Hvor vi går i dybden med brugen af UI Router til at route til komponenter, bør begrebet smarte og dumme komponenter diskuteres.

En smart komponent er en, der er meget bevidst om API’et og de data, der driver et view. Det betyder, at den i sin controller typisk foretager et servicekald ved initialisering af komponenten. Den ved, hvad der kræves for at foretage opkaldet, og hvilket svar den skal forvente fra API’et.

På den anden side er der dumme komponenter, som ved, hvad de skal gøre med et indleveret objekt eller en værdi, og hvilke interaktioner den er ansvarlig for. Den interagerer typisk ikke med nogen tjenester. De fleste interaktioner resulterer i et callback til en overordnet komponent for at videregive oplysninger tilbage opad, som skal bruges
af en smart komponent, eller er udelukkende relateret til visningsændringer.

For genanvendelighedens skyld er dumme komponenter typisk de mest genanvendelige (tænk på containere med overskrifter, navigationslinjer, valgbokse osv.) Smarte komponenter er gode til at opbygge komplette applikationer fra et højt niveau, men de kan ikke tilpasses særlig godt.

Den bedste måde at gøre en komponent dum på er at fjerne API-opkaldene fra controllerne og finde en måde at levere disse data på via en eller anden form for binding. Dette er nyttigt, hvis du allerede har de samme data, som en smart komponent har brug for, men ikke ønsker at lave to hits til serveren for at få dem.

Skrivning af en applikation som en komponent

Med overgangen til komponentiserede applikationer var der tankeskift i forhold til, hvordan vi ser på applikationer. Hele applikationer kan ses som en komponent. Dette har faktisk praktiske anvendelsesmuligheder. Hvis vi f.eks. skriver vores applikation som en komponent, kan vi tage en stand alone webapplikation og potentielt sætte den ind i en hybrid webcontainer og lave en mobilapplikation ud fra den.

Den bedste måde at skrive en applikation som en komponent på er at udnytte de indlejrede visninger i UI Router. Dette kan til tider være en udfordring, men det giver mulighed for stor fleksibilitet ved at udskifte komponenter baseret
på applikationens tilstand.

Brug af komponenter i tilstandsdefinition ved hjælp af skabelon

Den første integration med routable komponenter var at, i stedet for at bruge en templateUrl-egenskab på tilstandsdefinitionen, var at bruge template-egenskaben, i stedet. Et eksempel på dette ville være som
følger:

Obenbart virker dette, men når hver eneste tilstand deklareres med et HTML-element, der blot er et enkelt HTML-element uden attributter, begynder det at blive kedeligt.

Givetvis er al logik og visning i forbindelse med den pågældende komponent isoleret og kan genbruges. Hvis du f.eks. beslutter dig for at pakke myComponent ind i en navigationsskabelon, kan du nu gøre det uden at skulle generere en ny komponent fra en skabelon havde du oprettet den samme tilstand som sådan:

Binding til komponenter

Hvordan skriver vi en fuld applikation som en dum komponent, når mange af vores ruter skal foretage tjenestekald for at vise de oplysninger, som en bruger ønsker at se?

Et muligt svar på dette er at løse de data, der er nødvendige for, at komponenten kan fungere, fra ruten og derefter binde dem til komponenten via komponentens bindinger. Der er to tilgange til at gøre dette:

  1. Opret en smart komponent, der omslutter en dum komponent. Den smarte komponents eneste formål er at foretage et servicekald og binde korrekt til den dumme komponent.
  2. Brug resolve-funktionaliteten i UI-routeren til at resolve data direkte til den dumme komponent.

Der er nogle indlysende kompromiser ved begge muligheder. Med en smart komponentwrapper har du en ekstra komponent, som du skal vedligeholde. Ved at løse op til komponenten ved hjælp af UI Router binder du dig selv til routerens evne, og det er også vanskeligere at administrere undtagelseshåndtering.

Når det er sagt, er det ekstremt enkelt at oprette routable komponenter via UI Router’s bindinger, og UI Router er kraftig nok og giver stor funktionalitet i en sådan grad, at hvis den er i dit projekt, vil den sandsynligvis forblive der indtil en fuldstændig omskrivning af et program.

For at binde til en komponent i den stabile udgave af UI Router (0.x.x) opretter UI Router et $resolve-objekt i den kontekst, som den brugte til at kompilere indholdet af ui-view.

Dette kan bruges til at binde til en komponentdeklaration i template-egenskaben i tilstandsdefinitionen.

Det giver os mulighed for at fjerne UserService-afhængigheden fra user-komponenten. For de smarte komponenter, der blot foretager et servicekald og derefter viser oplysningerne, kan vi faktisk også fjerne en hel controller.

Binding til komponenter – 1.0.0.0-beta.x

Med udgivelsen af [email protected] blev component-egenskaben tilføjet til objektet til tilstandsdefinitionen. Dette gør det muligt for udvikleren at binde direkte til en komponent som defineret på angularmodulet. Det eliminerer behovet for at have en skabelon, der indeholder et enkelt element, som vi tidligere havde set.

Leave a Reply