Ví dụ về CRUD cho Angular 10 ( Frontend ) cho các bạn mới bắt đầu
19th Aug 2021Ví dụ dưới đây rất cơ bản để bắt đầu học về Angular 10 trở lên. Chúc các bạn theo nghề lập trình hạnh phúc.
Install Angular 10
npm install -g @angular/cli@10 ng version
1 – Create app
ng new app-tutofox
Would you like to add Angular routing? (y/N): y
2 – Install bootstrap
ng add @ng-bootstrap/ng-bootstrap
3 – Create module
ng generate module person --routing
4 – Create component
ng generate component person/index ng generate component person/create ng generate component person/edit
5 – Create routes
src/app/person/person-routing.module.ts
import { IndexComponent } from './index/index.component'; import { CreateComponent } from './create/create.component'; import { EditComponent } from './edit/edit.component'; const routes: Routes = [ { path: 'person', redirectTo: 'person/index', pathMatch: 'full'}, { path: 'person/index', component: IndexComponent }, { path: 'person/create', component: CreateComponent }, { path: 'person/edit/:idPerson', component: EditComponent } ];
6 – Create interface
ng generate interface person/person
src/app/person/person.ts
export interface Person { id: number; name: string; email: string; phone: number; }
7 – Create services
ng generate service person/person
src/app/person/person.service.ts
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { Person } from './person'; @Injectable({ providedIn: 'root' }) export class PersonService { private apiURL = "http://localhost:8000/api/person/"; httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) } constructor(private httpClient: HttpClient) { } getAll(): Observable<Person[]> { return this.httpClient.get<Person[]>(this.apiURL) .pipe( catchError(this.errorHandler) ) } create(person): Observable<Person> { return this.httpClient.post<Person>(this.apiURL, JSON.stringify(person), this.httpOptions) .pipe( catchError(this.errorHandler) ) } find(id): Observable<Person> { return this.httpClient.get<Person>(this.apiURL + id) .pipe( catchError(this.errorHandler) ) } update(id, person): Observable<Person> { return this.httpClient.put<Person>(this.apiURL + id, JSON.stringify(person), this.httpOptions) .pipe( catchError(this.errorHandler) ) } delete(id){ return this.httpClient.delete<Person>(this.apiURL + id, this.httpOptions) .pipe( catchError(this.errorHandler) ) } errorHandler(error) { let errorMessage = ''; if(error.error instanceof ErrorEvent) { errorMessage = error.error.message; } else { errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`; } return throwError(errorMessage); } }
8 – Components
Component Index
src/app/person/index/index.component.ts
import { Component, OnInit } from '@angular/core'; import { PersonService } from '../person.service'; import { Person } from '../person'; @Component({ selector: 'app-index', templateUrl: './index.component.html', styleUrls: ['./index.component.css'] }) export class IndexComponent implements OnInit { persons: Person[] = []; // constructor() { } constructor(public personService: PersonService) { } ngOnInit(): void { this.personService.getAll().subscribe((data: Person[])=>{ this.persons = data; console.log(this.persons); }) } deletePerson(id){ this.personService.delete(id).subscribe(res => { this.persons = this.persons.filter(item => item.id !== id); console.log('Person deleted successfully!'); }) } }
src/app/person/index/index.component.html
<section> <div class="d-flex justify-content-between"> <h4>List person</h4> <a routerLink="/person/create" class="btn btn-success">Create New Person</a> </div> <br> <table class="table "> <tr> <th>ID</th> <th>Name</th> <th>Email</th> <th>Phone</th> <th width="220px">Action</th> </tr> <tr *ngFor="let person of persons"> <td>{{ person.id }}</td> <td>{{ person.name }}</td> <td>{{ person.email }}</td> <td>{{ person.phone }}</td> <td> <a href="#" [routerLink]="['/person/', 'edit', person.id ]" class="btn btn-primary">Edit</a> <button type="button" (click)="deletePerson(person.id)" class="btn btn-danger">Delete</button> </td> </tr> </table> </section>
Component Create
src/app/person/create/create.component.ts
import { Component, OnInit } from '@angular/core'; import { PersonService } from '../person.service'; import { Router } from '@angular/router'; import { FormGroup, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-create', templateUrl: './create.component.html', styleUrls: ['./create.component.css'] }) export class CreateComponent implements OnInit { form: FormGroup; constructor( public personService: PersonService, private router: Router ) { } ngOnInit(): void { this.form = new FormGroup({ name: new FormControl('', [ Validators.required, Validators.pattern('^[a-zA-ZÁáÀàÉéÈèÍíÌìÓóÒòÚúÙùÑñüÜ \-\']+') ]), email: new FormControl('', [ Validators.required, Validators.email ]), phone: new FormControl('', [ Validators.required, Validators.pattern("^[0-9]*$") ]) }); } get f(){ return this.form.controls; } submit(){ console.log(this.form.value); this.personService.create(this.form.value).subscribe(res => { console.log('Person created successfully!'); this.router.navigateByUrl('person/index'); }) } }
src/app/person/create/create.component.html
<div> <div class="d-flex justify-content-between"> <h4>Form customer</h4> <a href="#" routerLink="/person/index" class="btn btn-primaryt">Back</a> </div> <hr/> <form [formGroup]="form" (ngSubmit)="submit()"> <div class="form-group row"> <div class="col-md-6 "> <label for="title">Name:</label> <input formControlName="name" id="name" type="text" class="form-control"> <div *ngIf="f.name.touched && f.name.invalid" class="alert alert-danger"> <div *ngIf="f.name.errors.required">*Name is required.</div> <div *ngIf="f.name.errors.pattern">*The name must only contain letters.</div> </div> </div> </div> <div class="form-group row"> <div class="col-md-6 "> <label for="email">Email:</label> <input formControlName="email" id="email" type="text" class="form-control"> <div *ngIf="f.email.touched && f.email.invalid" class="alert alert-danger"> <div *ngIf="f.email.errors.required">*Email is required.</div> <div *ngIf="f.email.errors.email">*The email must be a valid email address.</div> </div> </div> </div> <div class="form-group row"> <div class="col-md-6 "> <label for="phone">Phone:</label> <input formControlName="phone" id="phone" type="text" class="form-control"> <div *ngIf="f.phone.touched && f.phone.invalid" class="alert alert-danger"> <div *ngIf="f.phone.errors.required">*Phone is required.</div> <div *ngIf="f.phone.errors.pattern">*The phone must only contain numbers.</div> </div> </div> </div> <button class="btn btn-primary" type="submit" [disabled]="!form.valid">Submit</button> </form> </div>
Component Edit
src/app/person/edit/edit.component.ts
import { Component, OnInit } from '@angular/core'; import { PersonService } from '../person.service'; import { ActivatedRoute, Router } from '@angular/router'; import { FormGroup, FormControl, Validators} from '@angular/forms'; import { Person } from '../person'; @Component({ selector: 'app-edit', templateUrl: './edit.component.html', styleUrls: ['./edit.component.css'] }) export class EditComponent implements OnInit { id: number; person: Person; form: FormGroup; constructor( public personService: PersonService, private route: ActivatedRoute, private router: Router ) { } ngOnInit(): void { this.id = this.route.snapshot.params['idPerson']; this.personService.find(this.id).subscribe((data: Person)=>{ this.person = data; }); this.form = new FormGroup({ name: new FormControl('', [ Validators.required, Validators.pattern('^[a-zA-ZÁáÀàÉéÈèÍíÌìÓóÒòÚúÙùÑñüÜ \-\']+') ]), email: new FormControl('', [ Validators.required, Validators.email ]), phone: new FormControl('', [ Validators.required, Validators.pattern("^[0-9]*$") ]) }); } get f(){ return this.form.controls; } submit(){ console.log(this.form.value); this.personService.update(this.id, this.form.value).subscribe(res => { console.log('Person updated successfully!'); this.router.navigateByUrl('person/index'); }) } }
src/app/person/edit/edit.component.html
<div class="container"> <div class="d-flex justify-content-between"> <h4>Edit person</h4> <a href="#" routerLink="/person/index" class="btn btn-primaryt">Back</a> </div> <hr> <form [formGroup]="form" (ngSubmit)="submit()"> <div class="form-group row"> <div class="col-md-6 "> <label for="title">Name:</label> <input formControlName="name" [(ngModel)]="person.name" id="name" type="text" class="form-control"> <div *ngIf="f.name.touched && f.name.invalid" class="alert alert-danger"> <div *ngIf="f.name.errors.required">*Name is required.</div> <div *ngIf="f.name.errors.pattern">*The name must only contain letters.</div> </div> </div> </div> <div class="form-group row"> <div class="col-md-6 "> <label for="email">Email:</label> <input formControlName="email" [(ngModel)]="person.email" id="email" type="text" class="form-control"> <div *ngIf="f.email.touched && f.email.invalid" class="alert alert-danger"> <div *ngIf="f.email.errors.required">*Email is required.</div> <div *ngIf="f.email.errors.email">*The email must be a valid email address.</div> </div> </div> </div> <div class="form-group row"> <div class="col-md-6 "> <label for="phone">Phone:</label> <input [(ngModel)]="person.phone" formControlName="phone" id="phone" type="text" class="form-control"> <div *ngIf="f.phone.touched && f.phone.invalid" class="alert alert-danger"> <div *ngIf="f.phone.errors.required">*Phone is required.</div> <div *ngIf="f.phone.errors.pattern">*The phone must only contain numbers.</div> </div> </div> </div> <button class="btn btn-primary" type="submit" [disabled]="!form.valid">Update</button> </form> </div>
9 – Configure person module
src/app/person/person.module.ts
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { PersonRoutingModule } from './person-routing.module'; import { IndexComponent } from './index/index.component'; import { CreateComponent } from './create/create.component'; import { EditComponent } from './edit/edit.component'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @NgModule({ declarations: [ IndexComponent, CreateComponent, EditComponent ], imports: [ CommonModule, PersonRoutingModule, FormsModule, ReactiveFormsModule ] }) export class PersonModule { }
10 – Configure App
src/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { PersonModule } from './person/person.module'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, PersonModule, HttpClientModule, NgbModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
src/app/app.component.html
<div class="container" style="padding:20px;"> <h1 style="text-align:center;"> <a href="/person/index"> Full Stack - Angular 10 & Laravel 8 </a> </h1> <hr> <main> <router-outlet></router-outlet> </main> </div>
Xem tiếp phần xây dựng Backend Laravel 8
>> Tiếp nối phần Frontend bằng Angular nay mình học Laravel 8 ( Backend )
Attachment | Size |
---|---|
angular-10-laravel-8-main.zip383.44 KB | 383.44 KB |
Add new comment