Bygg en WordPress-drevet frontend Et tilpasset direktiv for postoppføring

I den forrige delen av serien startet vi vår AngularJS-applikasjon, konfigurert ruting for forskjellige visninger og bygget tjenester rundt ruter for innlegg, brukere og kategorier. Ved å bruke disse tjenestene, er vi nå endelig i stand til å hente data fra serveren for å drive fremsiden.

I denne delen av serien vil vi jobbe for å bygge et egendefinert AngularJS-direktiv for funksjonen etter oppføring. I den nåværende delen av serien vil vi:

  • introdusere oss til AngularJS-direktiver og hvorfor vi skal lage en
  • Planlegg direktivet for postnoteringsfunksjonen og argumentene det vil ta
  • Lag et egendefinert AngularJS-direktiv for postoppføring sammen med sin mal

Så la oss begynne med å introdusere oss til AngularJS-direktiver og hvorfor vi trenger dem.

Innføring av AngularJS-direktiver

Direktiver i AngularJS er en måte å endre oppførselen til HTML-elementer og å gjenbruke en repeterbar del av kode. De kan brukes til å endre strukturen til et HTML-element og dets barn, og dermed er de en perfekt måte å introdusere tilpassede brukergrensesnitt på.

Mens vi analyserte wireframes i den første delen av serien, oppdaget vi at postnoteringsfunksjonen blir brukt i tre visninger, nemlig:

  1. Post notering
  2. Forfatterprofil
  3. Kategori innlegg notering

Så i stedet for å skrive separat funksjonalitet for å liste innlegg på alle disse tre sidene, kan vi lage et egendefinert AngularJS-direktiv som inneholder forretningslogikk for å hente innlegg ved hjelp av tjenestene vi opprettet i den tidligere delen av denne serien. Bortsett fra forretningslogikk, vil dette direktivet også inneholde gjengivelseslogikken for å vise innlegg på bestemte visninger. Det er også i dette direktivet at funksjonaliteten for postpaginering og henting av stillinger på bestemte kriterier vil bli definert.

Derfor skaper et egendefinert AngularJS-direktiv for postnoteringsfunksjonen oss å definere funksjonaliteten bare på ett sted, og dette vil gjøre det lettere for oss i fremtiden å utvide eller endre denne funksjonaliteten uten å måtte endre koden i alle tre tilfeller hvor den blir brukt.

Etter å ha sagt det, la oss begynne å kode vårt tilpassede direktiv for postnoteringsfunksjonen.

Planlegger egendefinert AngularJS-direktivet for postoppføring

Før vi begynner å skrive noen kode for å bygge direktivet for postnoteringsfunksjonen, la oss analysere funksjonaliteten som trengs i direktivet.

På det grunnleggende nivået trenger vi et direktiv som vi kunne bruke på våre synspunkter for postoppføring, forfatterprofil og kategorisiden. Dette betyr at vi skal opprette en tilpasset brukergrensesnitt-widget (eller en DOM-markør) som vi legger inn i vår HTML, og AngularJS vil ta vare på resten avhengig av hvilke alternativer vi gir for den aktuelle forekomsten av direktivet.

Derfor vil vi opprette en tilpasset brukergrensesnitts widget som er identifisert av følgende tag:

Men vi trenger også dette direktivet til å være fleksibelt, dvs. å ta argumenter som input og handle tilsvarende. Vurder brukerprofilsiden der vi bare vil ha innlegg som tilhører den bestemte brukeren som skal vises eller kategorisiden der innlegg som tilhører den kategorien vil bli oppført. Disse argumentene kan gis på følgende to måter:

  1. I nettadressen som parametere
  2. Direkt til direktivet som en attributtverdi

Å oppgi argumenter i nettadressen virker innfødt i API-en, slik vi allerede er kjent med det. Derfor kan en bruker hente et sett med innlegg som tilhører en bestemt bruker på følgende måte:

http://127.0.0.1:8080/#/posts?author=1

Ovennevnte funksjonalitet kan oppnås ved å bruke $ routeParams service levert av AngularJS. Det er her vi kunne få tilgang til parametere som er oppgitt av brukeren i nettadressen. Vi har allerede sett på det mens du registrerer ruter i den forrige delen av serien.

Når det gjelder å gi argumenter direkte til direktivet som en attributtverdi, kan vi bruke noe som følgende:

De post-args Attributt i den ovennevnte koden tar argumenter for å hente et bestemt sett med innlegg, og for øyeblikket tar det forfatter-ID. Denne attributtet kan ta noen argumenter for å hente innlegg som støttet av / WP / v2 / innlegg rute. Så hvis vi skulle hente et sett med innlegg skrevet av en bruker som har en ID på 1 og tilhører en kategori med ID 10, kan vi gjøre noe som følger:

De filter [katt] parameteren i koden ovenfor brukes til å hente et sett med innlegg som tilhører en bestemt kategori.

Paginering er også en viktig funksjon når du arbeider med innleggssider. Direktivet vil håndtere postpaginering, og denne funksjonen vil bli drevet av verdiene til X-WP-Total og X-WP-TotalPages overskrifter som returneres av serveren sammen med respons kroppen. Dermed kan brukeren navigere frem og tilbake mellom forrige og neste sett med innlegg.

Etter å ha bestemt seg for det skikkelige direktivet om etternotering, har vi nå et ganske solid fundament for å begynne å skrive koden.

Bygg et tilpasset direktiv for postoppføring

Å bygge et direktiv for funksjonen etter oppføring inneholder to trinn:

  1. Opprett forretningslogikken for å hente innlegg og håndtere andre ting.
  2. Opprett en visningsvisning for disse innleggene som dukker opp på siden.

Forretningslogikken for vårt tilpassede direktiv vil bli håndtert i direktivdeklarasjonen. Og for å gjengi data på DOM, vil vi opprette en egendefinert mal for oppføring av innlegg. La oss begynne med direktivdeklarasjonen.

Direktivdeklarasjon

Direktiver i AngularJS kan deklareres for en modul med følgende syntaks:

/ ** * Opprette et tilpasset direktiv for innlegg notering * / quiescentApp.directive ('postListing', [function () return ;]);

Her erklærer vi et direktiv på modulen vår ved hjelp av .direktiv () metode som er tilgjengelig i modulen. Metoden tar navnet på direktivet som det første argumentet, og dette navnet er nært knyttet til navnet på elementets tag. Siden vi vil at vårt HTML-element skal være , Vi gir en kamel-saksrepresentasjon av taggenavnet. Du kan lære mer om denne normaliseringsprosessen utført av AngularJS for å matche direktivnavn i den offisielle dokumentasjonen.

Merknaden vi bruker i koden ovenfor for å erklære vårt direktiv kalles sikkerhetsstabilitet av avhengighetsinjeksjon. Og i denne notasjonen gir vi en rekke avhengigheter som det andre argumentet som vil bli nødvendig av direktivet. For tiden har vi ikke definert noen avhengigheter for vårt tilpassede direktiv. Men siden vi trenger innlegg tjeneste for å hente innlegg (som vi opprettet i den forrige delen av serien) og de innfødte AngularJS-er $ routeParams og $ location tjenester for tilgang til nettadresseparametere og den nåværende banen, definerer vi dem som følger:

/ ** * Opprette et tilpasset direktiv for innleggsoppføring * / quiescentApp.directive ('postListing', ['$ routeParams', '$ location', 'Posts', funksjon ($ routeParams, $ location, Posts) : 'E', omfang: postArgs: '=', link: funksjon ($ omfang, $ elem, $ attr) ;]);

Disse avhengighetene blir da gjort tilgjengelig for funksjonen som er definert som det siste elementet i arrayet. Denne funksjonen returnerer et objekt som inneholder direktivdefinisjon. For tiden har vi to egenskaper i direktivdefinisjonsobjektet, dvs.. begrense og link.

De begrense alternativet definerer måten vi bruker direktiv i vår kode på, og det kan være fire mulige verdier for dette alternativet:

  1. EN: For å bruke direktivet som et attributt på et eksisterende HTML-element.
  2. E: For å bruke direktivet som et elementnavn.
  3. C: For å bruke direktivet som et klassenavn.
  4. M: For å bruke direktivet som en HTML-kommentar.

De begrense alternativet kan også akseptere enhver kombinasjon av de ovennevnte fire verdiene.

Siden vi vil at vårt direktiv skal være et nytt element , Vi setter begrensningsalternativet til E. Hvis vi skulle definere direktivet ved hjelp av attributter på et eksisterende HTML-element, kunne vi ha satt dette alternativet til EN. I så fall kan vi bruke

å definere direktivet i vår HTML-kode.

Den andre omfang Eiendom brukes til å endre omfanget av direktivet. Som standard er verdien av omfang eiendommen er falsk, noe som betyr at omfanget av direktivet er det samme som forelderens. Når vi overfører det til et objekt, opprettes et isolert omfang for direktivet, og alle data som må sendes til direktivet av foreldrene, sendes gjennom HTML-attributter. Dette er hva vi gjør i vår kode, og attributtet vi bruker er post-args, som blir normalisert inn i postArgs.

De postArgs eiendom i omfang objektet kan akseptere noen av følgende tre verdier:

  1. =: Betydning at verdien som gikk inn i attributtet ville bli behandlet som en gjenstand.
  2. @: Betydning av at verdien som gikk inn i attributtet ville bli behandlet som en vanlig streng.
  3. &: Betydning at verdien som gikk inn i attributtet ville bli behandlet som en funksjon.

Siden vi har valgt å bruke = verdi, hvilken som helst verdi som blir sendt inn i post-args attributtet ville bli behandlet som et JSON-objekt, og vi kunne bruke det objektet som et argument for å hente innlegg.

Den tredje eiendommen, link, brukes til å definere en funksjon som brukes til å manipulere DOM og definere APIer og funksjoner som er nødvendige for direktivet. Denne funksjonen er der all logikk i direktivet håndteres.

De link funksjonen aksepterer argumenter for omfangsobjektet, direktivets HTML-element og et objekt for attributter definert i direktivets HTML-element. For tiden passerer vi to argumenter $ omfang og $ elem for omfangsobjektet og HTML-elementet henholdsvis.

La oss definere noen variabel på $ omfang eiendom som vi skal bruke til å gjengi postnoteringsfunksjonen på DOM.

/ ** * Opprette et tilpasset direktiv for innleggsoppføring * / quiescentApp.directive ('postListing', ['$ routeParams', '$ location', 'Posts', funksjon ($ routeParams, $ location, Posts) : 'E', omfang: postArgs: '=', link: funksjon ($ omfang, $ elem, $ attr) // definere variabler på $ scope objektet $ scope.posts = []; $ scope.postHeaders = ; $ scope.currentPage = $ routeParams.page? Math.abs ($ routeParams.page): 1; $ scope.nextPage = null; $ scope.previousPage = null; $ scope.routeContext = $ location.path );;]);

Derfor har vi definert seks egenskaper på $ omfang objekt som vi kunne få tilgang til i DOM. Disse egenskapene er:

  1. $ innlegg: En matrise for å holde postobjekter som blir returnert av serveren.
  2. $ postHeaders: Et objekt for å holde overskriftene som vil bli returnert av serveren sammen med responslegemet. Vi vil bruke disse til å håndtere navigasjon.
  3. $ currentPage: En heltallvariabel som holder det nåværende sidenummeret.
  4. $ previousPage: En variabel som holder det forrige sidenummeret.
  5. $ nextpage: En variabel som holder neste side nummer.
  6. $ routeContext: For tilgang til den nåværende banen ved hjelp av $ location service.

De postArgs Egenskapen som vi tidligere definerte for HTML-attributter, vil allerede være tilgjengelig på $ omfang objekt inne i direktivet.

Nå er vi klare til å gjøre en forespørsel til serveren ved hjelp av innlegg tjeneste for å hente innlegg. Men før det må vi ta hensyn til argumentene fra brukeren som nettadresseparametere, samt parametrene som er oppgitt i post-args Egenskap. Og for det formålet vil vi opprette en funksjon som bruker $ routeParams service for å pakke ut URL-parametere og fusjonere dem med argumentene som er gitt gjennom post-args Egenskap:

/ ** * Opprette et tilpasset direktiv for innleggsoppføring * / quiescentApp.directive ('postListing', ['$ routeParams', '$ location', 'Posts', funksjon ($ routeParams, $ location, Posts) : 'E', omfang: postArgs: '=', link: funksjon ($ omfang, $ elem, $ attr) // definere variabler på $ scope objektet $ scope.posts = []; $ scope.postHeaders = ; $ scope.currentPage = $ routeParams.page? Math.abs ($ routeParams.page): 1; $ scope.nextPage = null; $ scope.previousPage = null; $ scope.routeContext = $ location.path ); // forberede spørringsargumenter var prepareQueryArgs = function () var tempParams = $ routeParams; slett tempParams.id; returnere angular.merge (, $ scope.postArgs, tempParams);;;]);

De prepareQueryArgs () Metoden i ovennevnte kode bruker angular.merge () metode, som strekker seg $ scope.postArgs objekt med $ routeParams gjenstand. Men før du smelter sammen disse to objektene, slettes den først id eiendom fra $ routeParams objekt ved hjelp av slette operatør. Dette er nødvendig siden vi skal bruke dette direktivet om kategori- og brukervisninger, og vi vil ikke at kategori- og bruker-ID-ene skal bli feiltolket som post-ID.

Etter å ha utarbeidet spørringsargumenter, er vi endelig klare til å ringe til serveren og hente innlegg, og det gjør vi med Posts.query () metode, som tar to argumenter:

  1. Et objekt som inneholder argumenter for å lage spørringen.
  2. En tilbakeringingsfunksjon som utføres etter spørringen er fullført.

Så vi skal bruke prepareQueryArgs () funksjon for å forberede et objekt for spørringsargumenter, og i tilbakeringingsfunksjonen, setter vi verdiene for visse variabler på $ omfang eiendom:

// gjør forespørselen og spørringsinnlegget Posts.query (prepareQueryArgs (), funksjon (data, overskrifter) $ scope.posts = data; $ scope.postHeaders = headers (); $ scope.previousPage = (($ scope.currentPage + 1)> $ scope.postHeaders ['x-wp-totalpages'])? Null: ($ scope.currentPage + 1); $ scope.nextPage = (($ scope.currentPage - 1)> 0)? scope.currentPage - 1): null;);

Tilbakeringingsfunksjonen blir sendt to argumenter for svaret og svarhodene. Disse er representert av data og overskrifter argumenter henholdsvis.

De overskrifter argument er en funksjon som returnerer et objekt som inneholder responsoverskrifter av serveren.

Resterende kode er ganske selvforklarende da vi setter verdien av $ scope.posts array. For å angi verdiene til $ scope.previousPage og $ scope.nextPage variabler, bruker vi x-wp-totalpages eiendom i postHeaders gjenstand.

Og nå er vi klare til å gjengi disse dataene på forsiden ved hjelp av en tilpasset mal for vårt direktiv.

Opprette en egendefinert mal for direktivet

Det siste vi må gjøre for å gjøre vårt direktivarbeid er å lage en egen mal for postoppføring og knytte den til direktivet. For det formål må vi endre direktivdeklarasjonen og inkludere a templateUrl eiendom som følgende:

/ ** * Opprette et tilpasset direktiv for innleggsoppføring * / quiescentApp.directive ('postListing', ['$ routeParams', '$ location', 'Posts', funksjon ($ routeParams, $ location, Posts) : 'E', omfang: postArgs: '=', templateUrl: 'views / directive-post-listing.html', link: funksjon ($ scope, $ elem, $ attr) ;]);

Dette templateUrl Egenskapen i koden ovenfor refererer til en fil som heter Direktivet-post-listing.html i visninger katalogen. Så lag denne filen i visninger mappe og lim inn i følgende HTML-kode:

 

God design er mye som tydelig tenkning gjort visuelt.

Utvalgte bilder

Av Bilal Shahid i sitater

Opprettet dager frem. Dominion. Subdue veldig har ånd oss ​​sjette fisken creepeth også. Først kjøtt en gang over. Du fyller på. Kan ikke kveld ett lys vil ikke. Flott for å gjøre fastament bilde. Livet hans begynnelse velsignet mindre kjøtt ånd velsignet hav skapt grønn stor begynnelse kan ikke ikke ugyldig flytte. Subdue kvelden gjør ånden mindre større alle levende grønne firmament vinget såg tre en divide hvor delt skal tørke meget mindre så, jord jorden. Lys deres.

Eldre innlegg Nyere innlegg

Dette er veldig grunnleggende HTML-kode som representerer en enkelt postoppføring og postpaginering. Jeg har kopiert den fra visninger / listing.html fil. Vi vil bruke noen AngularJS-direktiver, inkludert ng-repeat, ng-href, ng-src, og ng-bind-html, for å vise dataene som for tiden ligger i $ omfang egenskapen til direktivet.

Endre HTML-koden til følgende:

 

Post.title.rendered

Utvalgte bilder

Ved post.quiescent_author_name i category.name $ last? ": ','

Ovennevnte kode bruker ng-repeat Direktivet for å lure gjennom $ scope.posts array. Enhver eiendom som er definert på $ omfang objekt i direktivdeklarasjonen er tilgjengelig direkte i malen. Derfor refererer vi til $ scope.posts array direkte som innlegg i malen.

Ved å bruke ng-repeat direktivet, sikrer vi at article.post-entry Beholderen vil bli gjentatt for hvert innlegg i innlegg array og hvert innlegg refereres til som post i innerløkken. Dette post objekt inneholder data i JSON-formatet som returneres av serveren, og inneholder egenskaper som posttittel, post-ID, innleggsinnhold og den kjennetegnede bildelinken, som er et ekstra felt lagt til av følgesvenn-plugin.

I neste trinn erstatter vi verdier som posttittel, postkoblingen og den kjennetegnede bildelinken med egenskaper i post gjenstand.

For paginering, erstatt den forrige koden med følgende:

 
Nyere innlegg Eldre innlegg

Vi kommer først til routeContext eiendom, som vi definerte i vår direktivdeklarasjon, og suffiks det med ?page = parameter og bruk verdiene til neste side og forrige side variabler å navigere frem og tilbake mellom innlegg. Vi sjekker også for å se om koblingen til neste side eller forrige side ikke er null, Ellers legger vi til en .funksjonshemmet klasse til knappen som tilbys av Zurb Foundation.

Nå som vi har fullført direktivet, er det på tide å teste det. Og vi gjør det ved å plassere en tag i vår HTML, ideelt sett rett over

stikkord. Hvis du gjør det, betyr det at en innleggsliste vises over sidebeteksten. Ikke bekymre deg for formatering og stiler som vi skal håndtere dem i neste del av serien.

Så det er ganske mye det for å lage et egendefinert AngularJS-direktiv for funksjonen etter oppføring.

Hva skjer neste gang?

I den nåværende delen av serien om å skape en frontend med WP REST API og AngularJS, bygde vi et tilpasset AngularJS-direktiv for postnoteringsfunksjonen. Dette direktivet bruker innlegg tjeneste som vi opprettet i den tidligere delen av serien. Direktivet tar også brukerinngang i form av et HTML-attributt og gjennom URL-parametere.

I den avsluttende delen av serien begynner vi å arbeide med det endelige prosjektstykket, det vil si styrere for innlegg, brukere og kategorier og deres respektive maler.