Bij het maken van een app met één pagina moeten we een soort framework gebruiken om een deel van de klus voor ons te doen, zodat we ons kunnen concentreren op de feitelijke functionaliteit.
AngularJS past hier perfect, omdat functies zoals dynamische afhankelijkheidsinjectie en bi-directionele gegevensbinding gewoon geweldig zijn. Soms hebben we ook een server nodig. Als je voor PHP hebt gekozen, is Laravel misschien wel je beste optie, omdat het gemakkelijk is om mee te werken en behoorlijk krachtig.
In dit deel van de tutorial bouwen we de front-end van onze applicatie met behulp van AngularJS. Angular is een echt uniek framework. In plaats van de HTML te abstraheren of op een of andere manier DOM-manipulatie te bieden, breidden ze de HTML uit om het feit te verwerken dat het zeker niet was ontworpen om met dynamische gegevens te werken.
Daarom heeft Angular misschien wat meer leren nodig dan andere frameworks, maar het is de tijd echt waard.
Voordat we onze front-end gaan programmeren, moeten we het Laravel-onderdeel een beetje aanpassen. Ga naar app / views
, verwijder de voorbeelddingen die er zijn en maak het bestand met de naam home.php
. Laten we nu de lay-out maken.
Begin met de DOCTYPE
en de html
label:
Zoals je ziet, gebruiken we al wat AngularJS-dingen - het ng-app
richtlijn. Dit vertelt Angular om de genoemde module te gebruiken app
voor deze toepassing (we zullen het later definiëren). Voeg daarna de hoofd
met een titel en CSS:
Klantenmanagement
Nu kun je de script
tag in met Angular, zijn routingmodule en onze app:
Deze richtlijn vertelt Angular om de gevraagde sjabloon in dat element te plaatsen.
Hierna hoeven we alleen maar een route toe te voegen om de sjabloon te tonen (in app / routes.php
). Voeg dit toe vóór de routes voor controllers:
Route :: get ('/', function () return View :: make ('layout'););
Nu als u de server start (met php artisan serveren
) zou u onze basislay-out moeten zien wanneer u naar http: // localhost: 8000 / in uw browser navigeert:
Dit artikel gaat niet over alles wat met CSS te maken heeft, maar om de app tijdens het ontwikkelen aangenamer te maken, zullen we er wat stijl aan toevoegen. Ga naar de openbaar/
directory van uw app (deze staat naast app /
) en maak de style.css
met deze code erin:
lichaam font-family: Calibri, sans-serif; breedte: 800 px; marge: automatisch; a cursor: pointer; kleur blauw; tekstdecoratie: geen; tabel width: 100%; table thead tr background: #ccc; table tbody tr background: #ddd; table tbody tr: nth-child (2n + 1) background: #eee; table tr td: nth-child (1) text-align: center; table tr td: nth-child (3), table tr td: nth-child (4) text-align: right; .error color: red;
Open nu de app in uw browser en de lay-out moet worden gecentreerd met een leuker lettertype in de kop:
We beginnen met een moduleverklaring. Modules in Angular zijn vrijwel hetzelfde als in elke AMD-bibliotheek, maar met de toevoeging van afhankelijkheidsinjectie, wat erg handig is, zoals je zult zien. Hier is de verklaring van onze app module:
var app = angular.module ('app', ['ngRoute']);
De syntaxis is eenvoudig - eerst de naam van de module en dan de reeks afhankelijkheden - die we alleen zullen gebruiken ngRoute
hier om de navigatie af te handelen, die hierna gaat.
De routing wordt gedefinieerd in de modules config ()
methode:
app.config (function configure ($ routeProvider)
Dit is het moment waarop de afhankelijkheidsinjectie voor de eerste keer van start gaat - onze callback zal duren $ routeProvider
als het enige argument, en deze module zal worden geïnjecteerd door Angular.
Je moet ervoor zorgen dat de argumentnamen exact hetzelfde zijn als de modulenamen, omdat Angular ze gebruikt om de juiste modules te matchen.
Laten we nu de. Gebruiken $ routeProvider
om de routes in te stellen:
$ routeProvider .when ('/', controller: 'CustomersController', templateUrl: './templates/customers.html') .when ('/ customer /: id', controller: 'CustomerController', templateUrl: ' ./templates/customer.html '). anders (redirect:' / '); );
Zoals je kunt zien om een route te definiëren, moet je de wanneer()
methode van de provider (merk op dat ze kunnen worden geketend).
De eerste parameter is de URI en de tweede is een object met opties voor de route. Hier hechten we passende controllers en sjablonen aan elke route. In de tweede die we ook gebruiken :ID kaart
aan het einde om een routeparameter te markeren die we later zullen gebruiken. De anders()
methode definieert wat er zal gebeuren als een andere URI wordt gebruikt.
Voordat we de controllers schrijven, moeten we een genoemd ding maken fabriek
. fabriek
is een functie die een service retourneert, wat handig is als u functies voor het ophalen en instellen van gegevens wilt scheiden van de controllers (wat u natuurlijk altijd wilt doen). We definiëren het met behulp van de fabriek()
methode van de module:
app.factory ('Gegevens', functie Gegevens ($ http)
De eerste parameter is de naam van de service en de tweede is een functie die de service retourneert die met deze fabriek wordt gemaakt.
We zullen de gebruiken $ http
module om toegang te krijgen tot onze server met behulp van Ajax. Het biedt snelkoppelingsmethoden voor alle HTTP-methoden en elk daarvan retourneert een belofte (als je niet weet wat dat is kijk hier en hier).
We moeten de service retourneren als een object met alle methoden die in onze controllers worden gebruikt:
terug
De eerste zal KRIJGEN
alle klanten zodat we ze in een lijst kunnen tonen:
getCustomers: function getCustomers () return $ http.get ('/ customers / all'); ,
De tweede zal KRIJGEN
slechts één klant van hem ID kaart
:
getCustomer: function getCustomer (id) return $ http.get ('/ customers? id =' + id); ,
Derde wil POST
het verzoek om gebruiker aan de database toe te voegen:
addCustomer: function addCustomer (data) return $ http.post ('/ customers', data); ,
Het tweede argument in $ Http.post ()
zijn de gegevens die naar de server worden verzonden.
De volgende zal DELETE
de klant met de ID kaart
op voorwaarde dat:
removeCustomer: function removeCustomer (id) return $ http.delete ('/ customers? id =' + id); ,
Nu zullen er weinig soortgelijke zijn voor transacties. Eén om ze allemaal te krijgen:
getTransactions: function getTransactions (id) return $ http.get ('/ transactions? id =' + id); ,
Eén om een nieuwe toe te voegen:
addTransaction: function addTransaction (data) return $ http.post ('/ transactions', data); ,
En een om te verwijderen:
removeTransaction: function removeTransaction (id) return $ http.delete ('/ transactions? id =' + id); );
De controllers in Angular zijn (zoals de naam al doet vermoeden) een manier om het gedrag van de applicatie te beheersen. We zullen er een hebben voor elke sjabloon. Eerst maken we er een voor de hoofdpagina. Begin met het definiëren ervan:
app.controller ('CustomersController', functie CustomersController ($ scope, Data)
De tweede parameter hier is de constructorfunctie voor de controller. Het is het eerste argument ($ scope
) is de koppeling tussen de DOM en de controller. Het is het hart van de bidirectionele gegevensbinding van Angular. De tweede is de service van de fabriek die we eerder hebben gemaakt.
Nu krijgen we de klantenlijst van de server via onze service:
. Data.getCustomers () succes (parseCustomers);
Alle beloften in Angular bieden de succes()
en fout()
methoden die kunnen worden gebruikt om geschikte callbacks toe te voegen. Laten we nu de functie definiëren die de inkomende gegevens zal ontleden om deze op de pagina weer te geven:
function parseCustomers (data) $ scope.customers = data;
Ja, dat is alles wat nodig is om de sjabloon met gegevens te voeden. Geen behoefte aan innerHTML
/appendChild ()
-ish code.
We moeten ook de mogelijkheid bieden om klanten toe te voegen en te verwijderen. Laten we eerst een object maken in de scope waarin we de gegevens van de nieuwe klant bewaren:
$ scope.newCustomer = name: ", email:";
Op deze manier kunnen we voorkomen dat we toegang krijgen tot DOM wanneer de gebruiker een klant toevoegt. Nu de functie die de klant daadwerkelijk toevoegt:
$ scope.addCustomer = function addCustomer ()
Aangezien de volledige naam van de gebruiker in de tabel wordt weergegeven, is de invoer hiervoor dezelfde, dus we moeten deze splitsen om de voor- en achternaam te krijgen:
var names = $ scope.newCustomer.name.split (");
Nu noemen we de juiste functie van onze fabriek met de gegevens van $ scope
:
Data.addCustomer (first_name: names [0], last_name: names [1], email: $ scope.newCustomer.email)
Daarna voegen we succes- en foutluisteraars toe aan de teruggekeerde belofte:
.succes (customerAddSuccess) .error (customerAddError);
Laten we eerst de succes-callback definiëren:
function customerAddSuccess (data)
De gegevens
argument bevat de tekst van het antwoord. We moeten de $ scope.error
variabele:
$ scope.error = null;
Duw de nieuw toegevoegde klant naar $ scope.customers
:
$ Scope.customers.push (data);
En instellen $ scope.newCustomer
naar de oorspronkelijke staat om de ingangen te wissen:
$ scope.newCustomer = name: ", email:";
De fout terugbellen zal gewoon de $ scope.error
variabele naar de tekst ontvangen van de server:
function customerAddError (data) $ scope.error = data;
De functie om de klant te verwijderen, neemt de zijne ID kaart
als een parameter:
$ scope.removeCustomer = function removeCustomer (id)
We zullen ook een bevestigingsvenster weergeven zodat de gebruiker de actie kan annuleren:
if (bevestigen ('Wilt u deze klant echt verwijderen?'))
Als de gebruiker zeker weet dat hij wil doorgaan, verwijderen we de klant:
Data.removeCustomer (id) .success (customerRemoveSuccess);
De callback hier zal de klant moeten verwijderen $ scope.customers
gebruik van de id gekregen van de server:
function customerRemoveSuccess (data) var i = $ scope.customers.length; while (i--) if ($ scope.customers [i] .id == data) $ scope.customers.plice (i, 1);
De volledige code zou er als volgt uit moeten zien:
app.controller ('CustomersController', functie CustomersController ($ scope, Data) Data.getCustomers (). success (parseCustomers); function parseCustomers (data) $ scope.customers = data; $ scope.newCustomer = name: ", email:"; $ scope.addCustomer = function addCustomer () var names = $ scope.newCustomer.name.split ("); Data.addCustomer (first_name: names [0], last_name: names [1] , email: $ scope.newCustomer.email) .success (customerAddSuccess) .error (customerAddError); function customerAddSuccess (data) $ scope.error = null; $ scope.customers.push (data); $ scope.newCustomer = name: ", email:"; function customerAddError (data) $ scope.error = data; $ scope.removeCustomer = function removeCustomer (id) if (confirm ('Wilt u deze klant echt verwijderen? ? ')) Data.removeCustomer (id) .success (customerRemoveSuccess); function customerRemoveSuccess (data) var i = $ scope.customers.length; while (i--) if ($ scope.customers [i ] .id == data) $ scope.customers.plice (i, 1););
Om de gegevens daadwerkelijk aan onze gebruikers te tonen, moeten we een sjabloon maken. We definieerden het in de te volgen route ./templates/customers.html
, dus maak de public / templates
map en de customers.html
bestand erin.
Voeg eerst de kop toe zodat de gebruiker weet waar hij is:
Klanten
Vervolgens hebben we een tabel nodig met een mooie kop om de gegevens te tonen:
Voeg nu de tbody
element. En hier komt Angular's magie weer binnen. De ... gebruiken ng-repeat
richtlijn we vertellen Angular om het element te herhalen:
De syntaxis is dezelfde als in JavaScript's
voor in
lus. Nu hebben we toegang tot deklant
variabele om alle gegevens te krijgen die we nodig hebben. In Angular voegt u variabelen in met dubbele accolades:Klanten ID [-] customer.first_name customer.last_naam klanten email Er is ook een
ng-click
richtlijn die als eenbij klikken
callback van een evenement, we gebruiken het om de mogelijkheid toe te voegen om klanten te verwijderen. Vervolgens is er een voettekst met ingangen zodat de gebruiker nieuwe klanten kan toevoegen:[+] Wij gebruiken de
ng-model
om geschikte variabelen van het bereik naar de ingangen te binden, zodat ze worden bijgewerkt telkens als de waarde van de invoer verandert.Het laatste wat u moet doen is een foutmelding laten zien als die er is. Om dat te bereiken zullen we gebruiken
ng-voorstelling
richtlijn die alleen het element toont als gespecificeerde uitdrukking waar is:fout
Dat is het! Nu kunt u de app in uw browser openen en zou u dit moeten zien:
U kunt een nieuwe klant toevoegen door op het plusteken in de rechterbenedenhoek van de tabel te klikken.
Klant Controller
Laten we nu een controller maken voor een weergave met één klant:
app.controller ('CustomerController', functie CustomerController ($ scope, $ routeParams, Data)De gegevens ophalen
We krijgen de gegevens van de klant met behulp van
$ routeParams
module die alle routeparameters zoals de bevat:ID kaart
we hebben eerder aangegeven:Data.getCustomer ($ routeParams.id) .success (parseCustomer); function parseCustomer (data) $ scope.customer = data;De callback is vrijwel hetzelfde als in de
CustomersController
. Laten we nu alle transacties van de klant ophalen:Data.getTransactions ($ routeParams.id) .success (parseCustomersTransactions); function parseCustomersTransactions (data) $ scope.transactions = data; $ scope.sum = 0; for (var k in data) $ scope.sum + = parseFloat (data [k] .amount);De terugbelfunctie is iets anders dan de vorige, omdat we ook de som van de bedragen van de transacties willen weergeven. We moeten gebruiken
parseFloat ()
omdat Laravel drijvers als snaren stuurt.Nieuwe transacties toevoegen
De code zal sterk lijken op die gebruikt om nieuwe klanten te creëren:
$ scope.newTransaction = name: ", amount: 0; $ scope.addTransaction = function addTransaction () $ scope.newTransaction.customer_id = $ scope.customer.id; Data.addTransaction ($ scope.newTransaction) .success (transactionAddSuccess). fout (transactionAddError); function transactionAddSuccess (data) $ scope.error = null; data.amount = parseFloat (data.amount); $ scope.transactions.push (data); $ scope.sum + = data.amount; $ scope.newTransaction = name: ", amount: 0; function transactionAddError (data) $ scope.error = data;Het enige verschil is dat we de id van de klant aan de gegevens toevoegen, zodat de server weet wie de transactie is. Het succes callback is ook een beetje aangepast, omdat we de float moeten analyseren voordat deze wordt toegevoegd aan de
$ scope
en we moeten het bedrag aan onze som toevoegen.Transacties verwijderen
De code voor
removeTransaction ()
functie is bijna identiek aanremoveCustomer
anders zijn alleen in de variabelenamen:$ scope.removeTransaction = functie removeTransaction (id) if (bevestigen ('Wilt u deze transactie echt verwijderen?')) Data.removeTransaction (id) .success (transactionRemoveSuccess); functie transactionRemoveSuccess (data) var i = $ scope.transactions.length; while (i--) if ($ scope.transactions [i] .id == data) $ scope.sum - = $ scope.transactions [i] .amount; $ scope.transactions.splice (i, 1);Het resultaat
De hele controller zou er als volgt uit moeten zien:
app.controller ('CustomerController', functie CustomerController ($ scope, $ routeParams, Data) Data.getCustomer ($ routeParams.id) .success (parseCustomer); function parseCustomer (data) $ scope.customer = data; Gegevens .getTransactions ($ routeParams.id) .success (parseCustomersTransactions); function parseCustomersTransactions (data) $ scope.transactions = data; $ scope.sum = 0; for (var k in data) $ scope.sum + = parseFloat ( data [k] .amount); $ scope.newTransaction = name: ", amount: 0; $ scope.addTransaction = function addTransaction () $ scope.newTransaction.customer_id = $ scope.customer.id; Gegevens .addTransaction ($ scope.newTransaction) .success (transactionAddSuccess) .error (transactionAddError); function transactionAddSuccess (data) $ scope.error = null; data.amount = parseFloat (data.amount); $ scope.transactions.push (data); $ scope.sum + = data.amount; $ scope.newTransaction = name: ", amount: 0; function transactionAddError (data) $ scope.error = data; $ scope.removeTransaction = functi op removeTransaction (id) if (bevestigen ('Wilt u deze transactie werkelijk verwijderen?')) Data.removeTransaction (id) .success (transactionRemoveSuccess); functie transactionRemoveSuccess (data) var i = $ scope.transactions.length; while (i--) if ($ scope.transactions [i] .id == data) $ scope.sum - = $ scope.transactions [i] .amount; $ scope.transactions.splice (i, 1); );Klant sjabloon
De sjabloon voor één klant heeft geen nieuwe Angular-richtlijnen, dus maak gewoon een bestand met de naam
customer.html
inpublic / templates /
en plaats deze code daar:Klant informatie
Naam: customer.first_name customer.last_naam
E-mail: klanten email
Lijst met transacties
ID kaart Naam Bedrag Datum Transactie ID [-] transaction.name $ transaction.amount.toFixed (2) transaction.created_at [+] Som: $ sum.toFixed (2) fout
Merk op dat we gebruiken
toFixed (2)
om de drijvers af te ronden zodat ze slechts twee decimale velden hebben, omdat de manier waarop Laravel omgaat met drijvers in JSON.Nu kunt u de browser openen en klikken op een van de klanten die u hebt gemaakt. U zou de controller en sjabloon in actie moeten zien:
Conclusie
Als je na het eerste deel wat functionaliteit hebt toegevoegd, zou het toevoegen aan de front-end een kwestie moeten zijn van het toevoegen van enkele regels code hier en daar.
Ik hoop dat nadat je het artikel hebt gelezen en je app klaar is en werkt, je gaat nadenken over hoe je zonder Larular applicaties met één pagina kunt maken zonder AngularJS en elke PHP-app. Laat het me weten als je problemen hebt met een van de hier gepresenteerde kaders.