Når du oppretter en enkeltsidig app, bør vi bruke en slags ramme for å gjøre noe av jobben for oss, så vi kan fokusere på den faktiske funksjonaliteten.
AngularJS passer perfekt, fordi funksjoner som dynamisk avhengighetsinjeksjon og toveisbinding er bare bra. Noen ganger krever vi også en slags server. Hvis du har valgt PHP, kan Laravel være ditt beste alternativ, da det er lett å jobbe med og ganske kraftig.
I denne delen av opplæringen bygger vi forkant av søknaden vår ved hjelp av AngularJS. Angular er et helt unikt rammeverk. I stedet for å trekke opp HTML-en eller gi DOM-manipulering noen måte, utvidet de HTML-en for å håndtere det faktum at det ikke sikkert var designet for å jobbe med dynamiske data.
På grunn av det kan Angular trenge litt mer læring enn andre rammer, men det er virkelig verdt tiden.
Før vi begynner å programmere vår front-end, må vi endre Laravel-delen litt. Gå til app / visninger
, slett eksemplet ting som er der og opprett filen navngitt home.php
. La oss nå lage oppsettet.
Start med DOCTYPE
og html
stikkord:
Som du kan se bruker vi allerede noen AngularJS ting - the ng-app
direktiv. Dette forteller Angular å bruke modulen som heter app
for denne applikasjonen (vi definerer den senere). Deretter legger du til hode
med tittel og CSS:
Kundebehandling
Nå kan du sette manus
merker inn med Angular, det er rutemodul og vår app:
Dette direktivet forteller Angular å sette malen som ble forespurt i det elementet.
Deretter trenger vi bare å legge til en rute for å vise malen (i app / routes.php
). Legg til dette før rutene for kontroller:
Rute :: få ('/', funksjon () returvisning :: lage ('layout'););
Nå hvis du starter serveren (med php artisan tjene
) bør du se vår grunnleggende layout når du navigerer til http: // localhost: 8000 / i nettleseren din:
Denne artikkelen vil ikke fokusere på noe relatert til CSS, men for å gjøre appen mer behagelig for øyet mens du utvikler, vil vi legge til noe stil på det. Gå til offentlig/
katalog over appen din (den er ved siden av app /
) og opprett style.css
med denne koden i den:
kropp font-family: Calibri, sans-serif; bredde: 800px; margin: auto; en markør: pointer; farge: blå; tekst-dekorasjon: ingen; tabell bredde: 100%; bordtemaet tr bakgrunn: #ccc; tabell tbody tr bakgrunn: #ddd; tabell tbody tr: nth-child (2n + 1) bakgrunn: #eee; tabell tr td: nth-barn (1) text-align: center; tabell tr td: nth-barn (3), tabell tr td: nth-barn (4) text-align: right; .error color: red;
Åpne nå appen i nettleseren din, og layoutet bør være sentrert med en finere skrift i overskriften:
Vi starter med en moduldeklarasjon. Moduler i Angular er stort sett det samme som i et hvilket som helst AMD-bibliotek, men med tillegg av avhengighetsinjeksjon som er en veldig nyttig ting, som du vil se. Her er erklæringen fra vår app modul:
var app = angular.module ('app', ['ngRoute']);
Syntaxen er enkel - først går modulens navn, og deretter rekkevidden av avhengigheter - vi vil bare bruke ngRoute
her for å håndtere navigasjonen, som vil gå neste.
Rutingen er definert i modulens konfig ()
metode:
app.config (funksjonskonfigurere ($ routeProvider)
Her er når avhengighetsinjeksjonen sparker inn for første gang - vår tilbakeringing vil ta $ routeProvider
som det eneste argumentet, og denne modulen vil bli injisert av Angular.
Du må sørge for at argumentnavnene er nøyaktig det samme som modulnavnene, fordi Angular bruker dem til å matche de aktuelle modulene.
La oss faktisk bruke $ routeProvider
å sette opp ruter:
$ routeProvider .when ('/', controller: 'CustomersController', templateUrl: './templates/customers.html') .when ('/ customer /: id', controller: 'CustomerController', templateUrl: ' ./templates/customer.html ') .otherwise (omdirigering:' / '); );
Som du kan se for å definere en rute må du ringe når()
Fremgangsmåte for leverandøren (merk at de kan kjedes).
Den første parameteren er URI, og den andre er et objekt med rutealternativer. Her legger vi til rette kontrollører og maler til hver rute. I den andre bruker vi også : id
på slutten å markere en rute parameter som vi vil bruke senere. De ellers()
Metode definerer hva som vil skje hvis noen annen URI er tilgjengelig.
Før vi skriver kontrollerne, må vi lage en ting som heter fabrikk
. fabrikk
er en funksjon som returnerer en tjeneste, noe som er nyttig hvis du vil skille mellom datainnstillingene fra kontrollerne (som selvsagt er det du alltid vil gjøre). Vi definerer den ved hjelp av fabrikk()
Modulets metode:
app.factory ('Data', funksjon Data ($ http)
Den første parameteren er navnet på tjenesten, og den andre er en funksjon som returnerer tjenesten som skal opprettes ved hjelp av denne fabrikken.
Vi vil bruke $ http
modul for å få tilgang til vår server ved hjelp av Ajax. Den gir snarvei metoder for alle HTTP metoder og hver av dem gir et løfte (hvis du ikke vet hva som er å se her og her).
Vi må returnere tjenesten som et objekt med alle metodene som skal brukes i våre kontroller:
komme tilbake
Den første vil FÅ
alle kundene slik at vi kan vise dem på en liste:
getCustomers: function getCustomers () return $ http.get ('/ customers / all'); ,
Andre en vil FÅ
bare en kunde av hans id
:
getCustomer: funksjon getCustomer (id) return $ http.get ('/ customers? id =' + id); ,
Tredje vilje POST
forespørselen om å legge til bruker i databasen:
addCustomer: funksjon addCustomer (data) return $ http.post ('/ customers', data); ,
Det andre argumentet i $ Http.post ()
er dataene som skal sendes til serveren.
Neste vilje SLETT
kunden med id
sørget for:
removeCustomer: funksjon removeCustomer (id) return $ http.delete ('/ customers? id =' + id); ,
Nå vil det være få lignende for transaksjoner. En for å få dem alle:
getTransactions: funksjon getTransactions (id) return $ http.get ('/ transaksjoner? id =' + id); ,
En for å legge til en ny:
addTransaction: funksjon addTransaction (data) return $ http.post ('/ transaksjoner', data); ,
Og en å slette:
removeTransaction: funksjon removeTransaction (id) return $ http.delete ('/ transaksjoner? id =' + id); );
Kontrollerne i Angular er (som navnet antyder) en måte å kontrollere programmets oppførsel på. Vi vil ha en for hver mal. Først vil vi lage en for hovedsiden. Begynn med å definere det:
app.controller ('CustomController', funksjon CustomersController ($ scope, Data)
Den andre parameteren her er konstruktørfunksjonen for kontrolleren. Det er første argumentet ($ omfang
) er koblingen mellom DOM og kontrolleren. Det er hjertet til Angular's toveisbinding. Den andre er tjenesten fra fabrikken som vi opprettet tidligere.
Nå vil vi få kundelisten fra serveren ved hjelp av vår tjeneste:
. Data.getCustomers () suksess (parseCustomers);
Alle løftene i Angular gir suksess()
og feil()
metoder som kan brukes til å legge til passende tilbakeringinger. La oss nå definere funksjonen som vil analysere innkommende data for å vise den på siden:
funksjon parseCustomers (data) $ scope.customers = data;
Ja, det er alt som trengs for å mate malen med data. Ingen behov for noen innerhtml
/appendChild ()
-ish kode.
Vi må også gi muligheten til å legge til og fjerne kunder. Først la oss lage et objekt i omfanget der vi vil holde dataene til den nye kunden:
$ scope.newCustomer = navn: ", email:";
På denne måten kan vi unngå å få tilgang til DOM når brukeren legger til en kunde. Nå funksjonen som faktisk vil legge til kunden:
$ scope.addCustomer = funksjon addCustomer ()
Siden brukerens fulle navn vil bli vist i tabellen, vil innspillet for det være det samme, så vi må dele det for å få for- og etternavn:
var navn = $ scope.newCustomer.name.split (");
Nå kaller vi den aktuelle funksjonen fra fabrikken med dataene fra $ omfang
:
Data.addCustomer (first_name: navn [0], etternavn: navn [1], e-post: $ scope.newCustomer.email)
Deretter legger vi til suksess- og feillyttere til løftet returnert:
.suksess (customerAddSuccess) .error (customerAddError);
La oss definere suksess tilbakeringingen først:
funksjon kundeAddSuccess (data)
De data
argumentet inneholder svarets tekst. Vi må tømme $ scope.error
variabel:
$ scope.error = null;
Skyv den nylig tilførte kunden til $ scope.customers
:
$ Scope.customers.push (data);
Og sett $ scope.newCustomer
til sin opprinnelige tilstand for å rydde inngangene:
$ scope.newCustomer = navn: ", email:";
Feil tilbakeringingen vil bare sette inn $ scope.error
variabel til teksten mottatt fra serveren:
funksjon kundeAddError (data) $ scope.error = data;
Funksjonen for å fjerne kunden vil ta hans id
som en parameter:
$ scope.removeCustomer = funksjon removeCustomer (id)
Vi vil også vise en bekreftelsesboks, slik at brukeren har mulighet til å avbryte handlingen:
hvis (bekreft ('Vil du virkelig fjerne denne kunden?'))
Hvis brukeren er sikker på at han vil fortsette, sletter vi kunden:
Data.removeCustomer (id) .success (customerRemoveSuccess);
Tilbakekallingen her må fjerne kunden fra $ scope.customers
bruker iden som er hentet fra serveren:
funksjon customerRemoveSuccess (data) var i = $ scope.customers.length; mens (i--) hvis ($ scope.customers [i] .id == data) $ scope.customers.splice (jeg, 1);
Den komplette koden skal se slik ut:
app.controller ('CustomerController', funksjon CustomersController ($ scope, Data) Data.getCustomers (). suksess (parseCustomers); funksjon parseCustomers (data) $ scope.customers = data; $ scope.newCustomer = ", email:"; $ scope.addCustomer = funksjon addCustomer () var names = $ scope.newCustomer.name.split ("); Data.addCustomer (first_name: names [0], last_name: names [1] , e-post: $ scope.newCustomer.email) .success (customerAddSuccess) .error (customerAddError); funksjon kundeAddSuccess (data) $ scope.error = null; $ scope.customers.push (data); $ scope.newCustomer = navn: ", e-post:"; funksjon kundeAddError (data) $ scope.error = data; $ scope.removeCustomer = funksjon removeCustomer (id) hvis (bekreft ('Vil du virkelig fjerne denne kunden () ] .id == data) $ scope.customers.splice (jeg, 1);));
For å faktisk vise dataene til brukerne må vi lage en mal. Vi definerte det i ruten for å være ./templates/customers.html
, så skape offentlige / maler
katalog og customers.html
filen i den.
Først legg til overskriften slik at brukeren vet hvor han er:
kunder
Deretter trenger vi et bord med en fin overskrift for å vise dataene:
Legg nå til tbody
element. Og her er hvor Angulars magi kommer inn igjen. Bruker ng-repeat
Direktiv vi forteller Angular å gjenta elementet:
Syntaxen er som i JavaScript
for i
sløyfe. Nå kan vi få tilgang tilkunde
variabel for å få alle dataene vi trenger. I Angular setter du inn variabler ved hjelp av dobbeltkrøllede bånd:Kunde ID [-] customer.first_name customer.last_name customer.email Det er også en
ng-klikk
direktiv som vil fungere som enved trykk
Event tilbakeringing, vi bruker det for å legge til muligheten til å fjerne kunder. Deretter er det en footer med innganger, slik at brukeren kan legge til nye kunder:[+] Vi bruker
ng-modellen
Direktivet for å binde passende variabler fra omfanget til inngangene, slik at de oppdateres hver gang det er en endring i inngangsverdien.Det siste du må gjøre er å vise en feilmelding hvis det er noen. For å oppnå det vil vi bruke
ng-vis
direktiv som bare viser elementet hvis spesifisert uttrykk er sant:error
Det er det! Nå kan du åpne appen i nettleseren din og du bør se dette:
Du kan legge til ny kunde ved å klikke på plustegnet i nederste høyre hjørne av tabellen.
Kundekontroller
La oss nå lage en kontroller for en enkeltkundsvisning:
app.controller ('CustomerController', funksjon CustomerController ($ scope, $ routeParams, Data)Få dataene
Vi får kundens data ved hjelp av
$ routeParams
modul som inneholder alle ruteparametrene som: id
vi spesifiserte tidligere:Data.getCustomer ($ routeParams.id) .success (parseCustomer); funksjon parseCustomer (data) $ scope.customer = data;Tilbakeringingen er stort sett den samme som i
CustomersController
. La oss nå få alle kundens transaksjoner:Data.getTransactions ($ routeParams.id) .success (parseCustomersTransactions); funksjon parseCustomersTransactions (data) $ scope.transactions = data; $ scope.sum = 0; for (var k i data) $ scope.sum + = parseFloat (data [k] .amount);Tilbakeringingen er litt annerledes enn den siste fordi vi også vil vise summen av transaksjonenes beløp. Vi må bruke
parseFloat ()
fordi Laravel sender flyter som strenge.Legge til nye transaksjoner
Koden vil være svært lik den som brukes til å skape nye kunder:
$ scope.newTransaction = navn: ", mengde: 0; $ scope.addTransaction = funksjon addTransaction () $ scope.newTransaction.customer_id = $ scope.customer.id; Data.addTransaction ($ scope.newTransaction) .success (transactionAddSuccess) .error (transactionAddError); funksjonstransaksjonAddSuccess (data) $ scope.error = null; data.amount = parseFloat (data.amount); $ scope.transactions.push (data); $ scope.sum + = data.amount; $ scope.newTransaction = navn: ", mengde: 0; funksjonstransaksjonAddError (data) $ scope.error = data;Den eneste forskjellen er at vi legger kundens ID til dataene slik at serveren vet hvem transaksjon det er. Suksess tilbakeringingen er også litt modifisert, fordi vi må analysere flyten før du legger den til
$ omfang
og vi må legge til beløpet til summen vår.Fjerne transaksjoner
Koden for
removeTransaction ()
funksjonen er nesten identisk medremoveCustomer
å være forskjellig bare i variabelnavnene:$ scope.removeTransaction = funksjon removeTransaction (id) if (confirm ('Vil du virkelig fjerne denne transaksjonen?')) Data.removeTransaction (id) .success (transactionRemoveSuccess); funksjonstransaksjonRemoveSuccess (data) var i = $ scope.transactions.length; mens (i--) if ($ scope.transactions [i] .id == data) $ scope.sum - = $ scope.transactions [i] .amount; $ scope.transactions.splice (jeg, 1);Resultatet
Hele kontrolleren bør se slik ut:
app.controller ('CustomerController', funksjon CustomerController ($ scope, $ routeParams, Data) Data.getCustomer ($ routeParams.id) .success (parseCustomer); funksjon parseCustomer (data) $ scope.customer = data; Data .getTransactions ($ routeParams.id) .success (parseCustomersTransactions); funksjon parseCustomersTransactions (data) $ scope.transactions = data; $ scope.sum = 0; for (var k i data) $ scope.sum + = parseFloat data [k] .amount); $ scope.newTransaction = navn: ", mengde: 0; $ scope.addTransaction = funksjon addTransaction () $ scope.newTransaction.customer_id = $ scope.customer.id; Data (add.transaction) (data); $ scope.sum + = data.amount; $ scope.newTransaction = navn: ", mengde: 0; funksjonstransaksjonAddError (data) $ scope.error = data; $ scope.removeTransaction = functi på removeTransaction (id) if (confirm ('Vil du virkelig fjerne denne transaksjonen?')) Data.removeTransaction (id) .success (transactionRemoveSuccess); funksjonstransaksjonRemoveSuccess (data) var i = $ scope.transactions.length; mens (i--) if ($ scope.transactions [i] .id == data) $ scope.sum - = $ scope.transactions [i] .amount; $ scope.transactions.splice (jeg, 1); );Kunde mal
Malen for enkeltkunder har ingen nye Angular-direktiver, så bare lag en fil som heter
customer.html
ioffentlig / templates /
og plasser denne koden der:Kundeinformasjon
Navn: customer.first_name customer.last_name
E-post: customer.email
Transaksjonsliste
ID Navn Beløp Dato Transaksjons-ID [-] transaction.name $ transaction.amount.toFixed (2) transaction.created_at [+] Sum: $ sum.toFixed (2) error
Legg merke til at vi bruker
toFixed (2)
å runde flåtene, så de har bare to desimalfelt, fordi måten Laravel håndterer flyter i JSON.Nå kan du åpne nettleseren og klikke på en av kundene du opprettet. Du bør se kontrolleren og malen i aksjon:
Konklusjon
Nå, hvis du har lagt til noen funksjonalitet etter første del, inkludert den i frontend, bør det være å legge til noen linjer med kode her og der.
Jeg håper at etter at du har lest artiklene og appen din er ferdig og jobber, begynner du å tenke på hvordan du kan lage enkeltsidige programmer uten AngularJS og noen PHP-programmer uten Laravel. Gi meg beskjed hvis du hadde noen problemer med noen av rammene som presenteres her.