Tempo di lettura: 75 minuti
Angular:Realizza l’area amministrativa
L’area amministrativa, o meglio la Home della stessa sarà gestita dal componente admin/home-admin.component.ts per cui apritelo e modificate come di seguito il template:
<div class="container"> <div class="row banner"> <div class="col-md-12"> <div class="list-group"> <div class="list-group-item"> <div class="row-action-primary"> <h4 class="list-group-item-heading"><span class="fa fa-user"></span> Manage User</h4> </div> <div class="row-content"> <a [routerLink]="['/admin/users']" class="btn btn-info">All Users</a> <a [routerLink]="['/admin/users/create']" class="btn btn-primary">New User</a> </div> </div> </div> </div> </div> </div>
Come vedete si tratta solamente di una pagina che ci consente poi di accedere ad altro, nel nostro caso gestione degli Utenti.
Abilitiamone la rotta , aprite il file api.php ed aggiungete il percorso:
{path: 'admin', component: HomeAdminComponent},
non dimenticatevi di importare il componente:
import {HomeAdminComponent} from './admin/home-admin/home-admin.component';
proviamo su http://localhost:4200/admin.
Se fate click su all user verrete indirizzati su list user.
Modifichiamone anche gli stili, quindi diamo un po di margine ai button:
... styles: [ ` .btn { margin: 2px; } ` ] ...
ok!
Creare rotte amministrative come rotte secondarie
Laravel consente di creare un gruppo di route , che consente di condividere attributi (name space, middleware, ecc…) . In Angular, possiamo fare la stessa cosa!
Per prima cosa, creiamo un nuovo file chiamato admin.routes.ts per memorizzare tutti i nostri percorsi di amministrazione :
src/app/admin/admin.routes.ts
import {Routes} from '@angular/router'; import {HomeAdminComponent} from './home-admin/home-admin.component'; import {ListAdminComponent} from './list-admin/list-admin.component'; export const adminRoutes: Routes = [ { path: '', component: HomeAdminComponent}, {path: 'users', component: ListAdminComponent}, ];
Abbiamo creato un nuovo array di rotte chiamato adminRoutes . Ogni rotta ha anche un percorso ( users) e un componente ( ListAdminComponent), che viene utilizzato per gestire la rotta.
Quindi, apri app.routing-module.ts e trova:
{path: 'admin', component: HomeAdminComponent}, {path: 'admin/users', component: ListAdminComponent},
sostituisci con:
{ path: 'admin', component: HomeAdminComponent, children: adminRoutes}
ricordati di importare :
import {HomeAdminComponent} from './admin/home-admin/home-admin.component';
e
import {adminRoutes} from './admin/admin.route';
Ora per gestire le rotte dei figli realiziamo il componente admin/dashboard.component.ts il quale fungerà da componente radice nella nostra area amministrativa:
ng g c admin/dashboard -is --flat
lo abbiamo creato con uno stile in linea visto che non verrà toccato, il –flat vuol dire realizzalo senza directory.
Apritelo , nel template cancellate tutto ed aggiungiamo il router-outlet:
import {Component, OnInit} from '@angular/core'; @Component({ selector: 'app-dashboard', template: ` <router-outlet></router-outlet> `, styles: [] }) export class DashboardComponent implements OnInit { constructor() { } ngOnInit(): void { } }
bene quindi modifichiamo il file app.routing.module.ts:
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import {AboutComponent} from './components/about/about.component'; import {ContactComponent} from './components/contact/contact.component'; import {HomeComponent} from './components/home/home.component'; import {adminRoutes} from './admin/admin.route'; import {DashboardComponent} from './admin/dashboard.component'; const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full'}, {path: 'home', component: HomeComponent}, {path: 'about', component: AboutComponent}, {path: 'contact', component: ContactComponent}, { path: 'admin', component: DashboardComponent, children: adminRoutes} ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
come vedete importo il componente DashBoard e lo richiamo nella path relativa al children adminRoutes (al posto di HomeAdminComponent).
Ora aprite adminRoutes.ts e semplicemente modificate da così:
import {Routes} from '@angular/router'; import {ListAdminComponent} from './list-admin/list-admin.component'; import {HomeAdminComponent} from './home-admin/home-admin.component'; export const adminRoutes: Routes = [ { path: 'admin', component: HomeAdminComponent}, {path: 'users', component: ListAdminComponent}, ];
a così:
import {Routes} from '@angular/router'; import {ListAdminComponent} from './list-admin/list-admin.component'; import {HomeAdminComponent} from './home-admin/home-admin.component'; export const adminRoutes: Routes = [ { path: '', component: HomeAdminComponent}, {path: 'users', component: ListAdminComponent}, ];
in partica una path vuota relativa al componente HomeAdminComponent in modo tale che accedo subito sullo stesso quando si naviga verso admin :
http://localhost:4200/admin
http://localhost:4200/admin/users
Angular:Elenca tutti gli User
E’ arrivato il momento di visualizzare tutti gli utenti e dare la possibilità di aggiungere lato admin o eliminarli.
Aprite il component admin/list-admin.component.ts e modificate da così:
import {Component, OnInit} from '@angular/core'; import {UserService} from '../../services/user.service'; import {User} from '../../models/user'; @Component({ selector: 'app-list-admin', template: ` <div class="container"> <div class="row"> <div class="col-md-12 text-center mt-lg-auto"> <h1>ADMIN LIST</h1> </div> </div> </div> `, styles: [ ` h1 { color: orange; font-size: 15vh; font-family: 'Big Shoulders Inline Text', cursive; } ` ] }) export class ListAdminComponent implements OnInit { users: User; constructor(private userService: UserService) { } // LETTURA DATI getUser(): any { return this.userService.getUsers() .subscribe(res => { this.users = res; console.log(this.users); }); } ngOnInit(): void { this.getUser(); } }
a così:
import {Component, OnInit} from '@angular/core'; import {UserService} from '../../services/user.service'; import {User} from '../../models/user'; @Component({ selector: 'app-list-admin', template: ` <div class="container"> <div class="col-md-12"> <div class="table-responsive"> <table class="table"> <thead> <tr> <th>Id</th> <th>Name</th> <th>Email</th> </tr> </thead> <tbody> <tr *ngFor="let user of users"> <td>{{user.id}}</td> <td>{{user.name}} </td> <td>{{user.email}} </td> <td> <a [routerLink]="['/users/edit']" class="btn btn-info"> Edit</a> <a [routerLink]="['/users/delete']" class="btn btn-danger"> Delete</a> </td> </tr> </tbody> </table> </div> </div> </div> `, styles: [` .btn { margin: 2px; } `] }) export class ListAdminComponent implements OnInit { users: User[]; constructor(private userService: UserService) { } // LETTURA DATI getUser(): any { return this.userService.getUsers() .subscribe(res => { this.users = res; console.log(this.users); }); } ngOnInit(): void { this.getUser(); } }
users deve essere di tipo User[], lo stesso vale su services/user.service.ts:
import { Injectable } from '@angular/core'; import {HttpClient} from '@angular/common/http'; import {Observable} from 'rxjs'; import {User} from '../models/user'; const API = `http://127.0.0.1:8000/api/v1/users`; @Injectable({ providedIn: 'root' }) export class UserService { constructor(private http: HttpClient) { } // VISUALIZZARE LA LISTA USER getUsers(): Observable<User[]> { return this.http.get<User[]>(API); } }
Miglioriamo il layout UX aggiungendo alcuni pulsanti per aggiungere utenti lato admin rapidamente e tornare al nostro pannello di amministrazione.
Apri list-admin.component.ts e trova:
<div class="container">
aggiungi di seguito:
<div class="col-md-12"> <div> <a [routerLink]="['/admin/']" class="btn btn-light"> Back</a> <a [routerLink]="['/admin/users/create']" class="btn btn-success"> New User</a> </div> </div>
Forms in Angular: template-driven
I moduli sono solitamente la parte più cruciale di un’applicazione. Usiamo i moduli per fare molte cose: convalidare l’input degli utenti, visualizzare gli errori, trasformare i dati, ecc. Fortunatamente, Angular fornisce tutto ciò di cui abbiamo bisogno per costruire un buon modulo.
Ci sono due modi che possiamo usare per scrivere un modulo in Angular:
- Template-driven —Basato sui modelli : come suggerisce il nome, costruiremo i nostri moduli principalmente nei nostri modelli. Questo metodo è adatto per moduli semplici che richiedono una semplice convalida.
- Code-driven : questo è un metodo nuovo ma potente che possiamo usare per costruire forme reattive. Creeremo moduli direttamente nel nostro componente.
Puoi leggere la documentazione ufficiale per saperne di più sui moduli.
Li vedremo entrambi!
Innanzitutto aprite app.module.ts ed importiamo il modulo relativo al form (template-driven):
import { FormsModule } from '@angular/forms';
inseritolo negli imports:
imports: [ routes, BrowserModule, HttpClientModule, FormsModule, ],
FormsModule contiene alcune direttive che possiamo aggiungere a un modulo normale e trasformarlo in un potente modulo per Angular.
Quindi realiziamo il componente che si occuperà di inserire nuovi utenti nella nostra applicazione:
ng g c admin/admin-user-create -is
E:\TODO-ANGULAR\angular-laravel\ngbook>ng g c admin/admin-user-create -s CREATE src/app/admin/admin-user-create/admin-user-create.component.ts (296 bytes) UPDATE src/app/app.module.ts (1302 bytes) E:\TODO-ANGULAR\angular-laravel\ngbook>
bene aggiungiamolo nei percorsi su admin-routes.ts :
export const adminRoutes: Routes = [ { path: '', component: HomeAdminComponent}, {path: 'users', component: ListAdminComponent}, { path: 'users/create', component: AdminUserCreateComponent} ];
non dimenticarti di importarlo:
import {AdminUserCreateComponent} from './admin-user-create/admin-user-create.component';
aprite admin/admin-user-create.component.ts ed aggiungete un semplice modulo di bootstrap:
<div class="container"> <div class="col-md-12"> <div> <a [routerLink]="['/admin/']" class="btn btn-default"> Back</a> </div> </div> <div class="col-md-12"> <div class="card card-body bg-light"> <form class="form-horizontal"> <h3 class="card-title">Add a new user</h3> <div class="form-group"> <label for="name" class="col-lg-2 control-label">Name</label> <div class="col-lg-12"> <input type="text" class="form-control" id="name" name="name" placeholder="Inserisci nome e cognome"> </div> </div> <div class="form-group"> <label for="email" class="col-lg-2 control-label">Email</label> <div class="col-lg-12"> <input type="email" class="form-control" id="email" name="email" placeholder="Inserisci email"> </div> </div> <div class="form-group"> <label for="password" class="col-lg-2 control-label">Password</label> <div class="col-lg-12"> <input type="password" class="form-control" id="password" name="password" placeholder="inserisci la password"> </div> </div> <div class="form-group"> <div class="col-lg-12"> <button class="btn btn-default">Cancel</button> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div> </div> </div>
ora se fate click su http://localhost:4200/admin/users/create vi troverete:
Quindi, come trasformiamo questa form in un form Angular.
È molto semplice. Tutto quello che devi fare è trovare:
<form class="form-horizontal">
ed aggiungere
<form class="form-horizontal" (ngSubmit)="createUser(createUserForm.value)" #createUserForm="ngForm">
#createUserForm è una reference variabile, potete scegliere il nome che volete.
Assegniamo i dati del nostro modulo a una variabile personalizzata chiamata createUserForm utilizzando ngForm . In questo modo, diciamo ad Angular: “Questo è il modulo che vogliamo che tu gestisca!”.
Usiamo anche l’associazione dell’output per rispondere nuovamente a un evento:
(ngSubmit)="createUser(createUserForm.value)
Utilizzando ngSubmit , quando premiamo il pulsante di invio, viene chiamato il metodo createUser () . Il createUserForm.value contiene i nostri dati del modulo.
Successivamente, dobbiamo aggiungere le direttive ngModel a tutti i campi di input:
Trova:
<input type="text" class="form-control" id="name" name="ame" placeholder="Inserisci nome e cognome"> <input type="email" class="form-control" id="email" name="email" placeholder="Inserisci email"> <input type="password" class="form-control" id="password" name="password" placeholder="Iserisci password">
ed aggiungi:
<input type="text" class="form-control" id="name" name="ame" placeholder="Inserisci nome e cognome" ngModel> <input type="email" class="form-control" id="email" name="email" placeholder="Inserisci email" ngModel> <input type="password" class="form-control" id="password" name="password" placeholder="Iserisci password" ngModel>
Il nostro modulo dovrebbe ora essere simile a:
admin-user-create.component.html
import {Component, OnInit} from '@angular/core'; @Component({ selector: 'app-admin-user-create', template: ` <div class="container"> <div class="col-md-12"> <div> <a [routerLink]="['/admin/']" class="btn btn-default"> Back</a> </div> </div> <div class="col-md-12"> <div class="card card-body bg-light"> <form class="form-horizontal" (ngSubmit)="createUser(createUserForm.value)" #createUserForm="ngForm"> <h3 class="card-title">Add a new user</h3> <div class="form-group"> <label for="name" class="col-lg-2 control-label">Name</label> <div class="col-lg-12"> <input type="text" class="form-control" id="name" name="name" placeholder="Inserisci nome e cognome" ngModel> </div> </div> <div class="form-group"> <label for="email" class="col-lg-2 control-label">Email</label> <div class="col-lg-12"> <input type="email" class="form-control" id="email" name="email" placeholder="Inserisci email" ngModel> </div> </div> <div class="form-group"> <label for="password" class="col-lg-2 control-label">Password</label> <div class="col-lg-12"> <input type="password" class="form-control" id="password" name="password" placeholder="inserisci la password" ngModel> </div> </div> <div class="form-group"> <div class="col-lg-12"> <button class="btn btn-default">Cancel</button> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div> </div> </div> `, styles: [] }) export class AdminUserCreateComponent implements OnInit { constructor() { } ngOnInit(): void { } }
quindi realiziamo il metodo createUser():
export class AdminUserCreateComponent implements OnInit { constructor() { } ngOnInit(): void { } createUser(user): void { console.log(user); } }
Ora, se inviiil modulo, dovremmo vedere i valori del modulo sulla console:
http://localhost:4200/admin/users/create
Invio della richiesta POST al backend utilizzando il service user
Aprite services/user.service.ts ed aggiungete il metodo addUser():
user.service.ts
addUser(user: User): Observable<any> { return this.http.post(API, user) .pipe( map((response) => response), catchError(this.errorHandler) ); } errorHandler(error: HttpErrorResponse): any { return throwError(error.error || {message: 'Server Error'}); }
Proprio come il metodo getUsers , questo restituisce un Observable . Come puoi vedere, utilizzo http.post per inviare una richiesta POST al nostro server. Il secondo argomento è l’ oggetto user .
Inoltre, aggiungiamo catchError
una nuova errorHandler
funzione per gestire gli errori:
catchError(this.errorHandler) errorHandler(error: HttpErrorResponse) { return throwError(error.error || {message: 'Server Error'}); }
questo è il metodo che utiliziamo per vedere a video se c’è un errore e quindi se qualche cosa andasse storto.
Usiamo l’ catchError
operator e l’ throwError
operator , quindi importiamoli dalla libreria RxJS :
import {catchError, map} from 'rxjs/operators'; import {Observable, throwError} from 'rxjs';
Tornando al nostro componente Admin User Create , ora possiamo aggiornare il metodo createUser come segue:
admin / admin-user-create.component.ts
createUser(user): void { this.userService.addUser(user) .subscribe(response => { this.user = response; console.log(this.user); } ); }
iniettate anche il service nel costruttore:
constructor(private userService: UserService) { }
Laravel:Creare un nuovo utente su END POINT
Il nostro backend non gestisce ancora la richiesta POST , quindi apriamo UserController (nell’ app Laravel) e aggiorniamo il metodo STORE come segue:
Http/Controllers/UserController.php
public function store(Request $request) { if ((!$request->email) || (!$request->name) || (!$request->password)) { $response = Response::json([ 'message' => 'Please enter all required fields' ], 422); return $response; } $user = new User(array( 'email' => trim($request->email), 'name' => trim($request->name), 'password' => bcrypt($request->password), )); $user->save(); $message = 'The user has been created successfully'; $response = Response::json([ 'message' => $message, 'data' => $user, ], 201); return $response; }
ricordatevi di importare:
use Illuminate\Support\Facades\Response;
Innanzitutto, controlliamo la richiesta. Se uno dei campi è vuoto, inviamo una risposta, dicendo che “Per favore inserisci tutti i campi obbligatori”.
se abbiamo abbastanza informazioni, creeremo un nuovo utente:
$user = new User(array( 'email' => trim($request->email), 'name' => trim($request->name), 'password' => bcrypt($request->password), )); $user->save();
Dopodiché, inviamo una risposta positiva, insieme ai dati dell’immagine:
$message = 'The user has been created successfully'; $response = Response::json([ 'message' => $message, 'data' => $user, ], 201); return $response;
È ora di aggiungere un nuovo utente! Vai al modulo e prova ad aggiungere un utente.
Controlla la scheda Console e dovresti vedere:
Ottimo! Ora puoi aggiungere un utente! Controlla il tuo database per assicurarti che sia stato creato un utente.
Nelle applicazioni del mondo reale, di solito reindirizziamo gli utenti a una pagina diversa dopo aver creato qualcosa.
Per farlo, possiamo usare router.navigate :
Angular – admin-ser-create.component.ts
createUser(user): void { this.userService.addUser(user) .subscribe(response => { this.user = response; console.log(this.user); this.router.navigate(['/admin/users']); } ); }
ricordati di importare il Router:
import {Router} from '@angular/router';
e di iniettarlo nel costruttore:
constructor(private userService: UserService, private router: Router) { }
Ecco il admin-user-create.component.ts aggiornato :
admin-user-create.component.ts
import {Component, OnInit} from '@angular/core'; import {UserService} from '../../services/user.service'; import {User} from '../../models/user'; import {Router} from '@angular/router'; @Component({ selector: 'app-admin-user-create', template: ` <div class="container"> <div class="col-md-12"> <div> <a [routerLink]="['/admin/']" class="btn btn-default"> Back</a> </div> </div> <div class="col-md-12"> <div class="card card-body bg-light"> <form class="form-horizontal" (ngSubmit)="createUser(createUserForm.value)" #createUserForm="ngForm"> <h3 class="card-title">Add a new user</h3> <div class="form-group"> <label for="name" class="col-lg-2 control-label">Name</label> <div class="col-lg-12"> <input type="text" class="form-control" id="name" name="name" placeholder="Inserisci nome e cognome" ngModel> </div> </div> <div class="form-group"> <label for="email" class="col-lg-2 control-label">Email</label> <div class="col-lg-12"> <input type="email" class="form-control" id="email" name="email" placeholder="Inserisci email" ngModel> </div> </div> <div class="form-group"> <label for="password" class="col-lg-2 control-label">Password</label> <div class="col-lg-12"> <input type="password" class="form-control" id="password" name="password" placeholder="inserisci la password" ngModel> </div> </div> <div class="form-group"> <div class="col-lg-12"> <button class="btn btn-default">Cancel</button> <button type="submit" class="btn btn-primary">Create</button> </div> </div> </form> </div> </div> </div> `, styles: [] }) export class AdminUserCreateComponent implements OnInit { user: User; constructor(private userService: UserService, private router: Router) { } ngOnInit(): void { } createUser(user): void { this.userService.addUser(user) .subscribe(response => { this.user = response; console.log(this.user); this.router.navigate(['/admin/users']); } ); } }
ora se provi ad aggiungere un nuovo utente verrai indirizzato sulla home di admin 😉