AngularJS og Laravel Etterbehandling Bygg en CRM

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.


Forberedelse

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:

Stilen

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:

Grunnleggende applikasjonsstruktur

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.

routing

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.


Fabrikk

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 alle kundene slik at vi kan vise dem på en liste:

getCustomers: function getCustomers () return $ http.get ('/ customers / all'); ,

Andre en vil 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); );

Kundekontroller

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.

Få listen

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.

Legge til nye kunder

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;  

Fjerne kunder

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); 

Resultatet

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);));

Klientmaler

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 til kunde 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 en ved 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 med removeCustomer å 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 i offentlig / 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.