這篇繼續透過Angular 呼叫 webapi完成資料Create、Delete、Update
修改WEB API controller,新增CRU
[HttpDelete]
[Route("delete/{id}")]
public async Task<int> DeleteAsync(long id)
{
return await _eventLogService.RemoveEventLogAsync(new[] { new EventLog { Id = id } });
}
[HttpPost]
[Route("create")]
public async Task<int> CreateAsync([FromBody]EventLogRequest request)
{
return await _eventLogService.CreateEventLogAsync(
new[] { new EventLog
{
Id=request.Id,
EventID=request.EventID,
Message=request.Message,
CreatedTime= DateTime.Parse(request.CreatedTime),
LogLevel="Test",
Exception=string.Empty
}
});
}
[HttpPut]
[Route("update")]
public async Task<int> UpdateAsync([FromBody]EventLogRequest request)
{
return await _eventLogService.UpdateEventLogAsync(
new[] { new EventLog
{
Id=request.Id,
EventID=request.EventID,
Message=request.Message,
CreatedTime= DateTime.Parse(request.CreatedTime),
LogLevel="Test",
Exception=string.Empty
} }
);
}
修改eventlog.service.ts,新增CUD
Note:因為我把rxjs upgrade到6.2.2,所以catcherror也需改寫
import { Injectable, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { Observable, Subject, empty , throwError, of } from 'rxjs';
import { map, filter, switchMap, catchError } from 'rxjs/operators';
@Injectable()
export class EventlogService {
myAppUrl: string = "";
constructor(private _http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
this.myAppUrl = baseUrl;
}
getEventLogs() {
return this._http.get(this.myAppUrl + "api/eventlog/all")
.pipe(
//map((response: Response) => response.json())
catchError(error => {
console.log(error);
return throwError(error);
})
);
}
getEventLogsById(id: number) {
return this._http.get(this.myAppUrl + "api/eventlog/" + id)
.pipe(
catchError(error => {
console.log(error);
return throwError(error);
})
);
}
deleteEventLog(id: number) {
return this._http.delete(this.myAppUrl + "api/eventlog/delete/" + id)
.pipe(
catchError(error => {
console.log(error);
return throwError(error);
})
);
}
createEventLog(eventlog) {
return this._http.post(this.myAppUrl + "api/eventlog/create/", eventlog)
.pipe(
catchError(error => {
console.log(error);
return throwError(error);
})
);
}
updateEventLog(eventlog) {
return this._http.put(this.myAppUrl + "api/eventlog/update", eventlog)
.pipe(
catchError(error => {
console.log(error);
return throwError(error);
})
);
}
errorHandler(error: Response) {
console.log(error);
return Observable.throw(error);
}
}
修改eventlog.component.ts,新增delete function
delete(id: number) {
var ans = confirm("Do you want to delete eventLog with Id: " + id);
if (ans) {
this._eventLogService.deleteEventLog(id).subscribe((result) => {
console.log(result);
this.getEventLogs();
})
}
}
新增eventlogAdd component,用來處理新增和更新
ng g c eventlogAdd
因為表單中會有一個日期控制項,我打算使用ng-bootstrap,所以先安裝該libary
npm install --save @ng-bootstrap/ng-bootstrap
note:我安裝完後,順便更新相關cli和rxjs
ng update @angular/cli
npm ls -g --depth=1
npm update rxjs@6.2.2
npm uninstall -g rxjs
npm install -g rxjs@6.2.2
修改app.module.ts
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
修改font CDN
@import url('https://fonts.googleapis.com/css?family=Ubuntu');
@import url('https://use.fontawesome.com/releases/v5.4.1/css/all.css');
Note: Font Awesome's Free CDN、fontawesome.com
修改eventlog-add.component.ts
import { Component, OnInit, Inject } from '@angular/core';
import { NgForm, FormBuilder, FormGroup, Validators, FormControl, ReactiveFormsModule } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Time, DatePipe } from '@angular/common';
import { NgbDateStruct, NgbCalendar, NgbDate } from '@ng-bootstrap/ng-bootstrap';
import { NgbTimeStruct } from '@ng-bootstrap/ng-bootstrap';
import { EventlogComponent } from '../eventlog/eventlog.component';
import { EventlogService } from '../service/eventlog.service'
@Component({
selector: 'app-eventlog-add',
templateUrl: './eventlog-add.component.html',
styleUrls: ['./eventlog-add.component.css']
})
export class EventlogAddComponent implements OnInit {
eventLogForm: FormGroup; // 宣告eventLogForm as FormGroup
title: string = "Create";
id: number;
datePipe = new DatePipe('en-US');
modelDate; // ngbDatepicker
constructor(private _fb: FormBuilder, private _avRoute: ActivatedRoute,
private _eventLogService: EventlogService, private _router: Router,
private _calendar: NgbCalendar) {
if (this._avRoute.snapshot.params["id"]) {
this.id = this._avRoute.snapshot.params["id"];
}
this.eventLogForm = this._fb.group({
id: 0, // 建立名為id,預設值0的formControl
eventID: ['', [Validators.required]], // Validators.required 必須值
message: ['', [Validators.required]],
createdTime: ['', [Validators.required]]
})
}
ngOnInit() {
if (this.id > 0) {
this.title = "Edit";
this._eventLogService.getEventLogsById(this.id)
.subscribe((result) =>
{
console.log(result[0]);// 只取第一個object
let dateParts = this.datePipe.transform(result[0].createdTime.substring(0, 10), 'M-d-y').split('-');
this.eventLogForm.controls["id"].setValue(result[0].id);
this.eventLogForm.controls["eventID"].setValue(result[0].eventID);
this.eventLogForm.controls["message"].setValue(result[0].message);
let currentDate: NgbDateStruct = {
year: parseInt(dateParts[2]),
month: parseInt(dateParts[0]),
day: parseInt(dateParts[1])
}; // date format
this.modelDate = currentDate;
//this.eventLogForm.setValue(result[0])
});
} else {
this.eventLogForm.controls["id"].setValue('');
}
this.eventLogForm.controls["id"].disable();
}
save() {
if (!this.eventLogForm.valid) {
return;
}
let currentDate= this.modelDate.year.toString() + "-" + this.modelDate.month.toString() + "-" + this.modelDate.day.toString();
this.eventLogForm.controls["createdTime"].setValue(currentDate);
if (this.title == "Create") {
this._eventLogService.createEventLog(this.eventLogForm.value)
.subscribe((result) => {
console.log(result);
this._router.navigate(['/eventlog']);
});
}
else if (this.title == "Edit") {
this._eventLogService.updateEventLog(this.eventLogForm.getRawValue()) // get value from each control
.subscribe((result) => {
console.log(result);
this._router.navigate(['/eventlog']); // go back to index
});
}
}
cancel() {
this._router.navigate(['/eventlog']);
}
}
修改template
<h3>EventLog {{title}}</h3>
<hr />
<!--
novalidate屬性,是為了要防止瀏覽器自己執行native驗證
[formGroup]="eventLogForm"是將template內的form元件關連controller中所建立的formGroup
#formDir="ngForm",產生一個ngForm實體
-->
<form [formGroup]="eventLogForm" (ngSubmit)="save()" #formDir="ngForm" novalidate>
<div class="form-group row">
<label class="control-label col-md-12" for="Id">Id</label>
<div class="col-md-4">
<!--formControlName="id", 將input與formGroup下為Id的formControl建立關連 -->
<input class="form-control" type="text" formControlName="id">
</div>
</div>
<div class="form-group row">
<label class="control-label col-md-12" for="EventID">EventID</label>
<div class="col-md-4">
<input class="form-control" type="text" formControlName="eventID" placeholder="required">
</div>
<!-- 按下submitted如有錯誤才顯示-->
<span class="text-danger" *ngIf="eventLogForm.hasError('required', 'eventID') && formDir.submitted">
EventID is required
</span>
</div>
<div class="form-group row">
<label class="control-label col-md-12" for="Message">Message</label>
<div class="col-md-4">
<input class="form-control" type="text" formControlName="message" placeholder="required">
</div>
<span class="text-danger" *ngIf="eventLogForm.hasError('required', 'message') && formDir.submitted">
Message is required
</span>
</div>
<div class="form-group row">
<label class="control-label col-md-12" for="CreatedTime">CreatedTime</label>
<div class="col-md-4">
<!--[(ngModel)]="modelDate" data雙向binding-->
<input class="form-control" type="text" placeholder="yyyy-mm-dd" formControlName="createdTime" data-val="true"
ngbDatepicker #d="ngbDatepicker" [(ngModel)]="modelDate">
<button class="btn" (click)="d.toggle()" type="button">
<i class="far fa-calendar-alt"></i>
</button>
</div>
<span class="text-danger" *ngIf="eventLogForm.hasError('required', 'createdTime') && formDir.submitted">
CreatedTime is required
</span>
</div>
<div class="form-group">
<!-- eventLogForm.valid 驗證都通過才enable -->
<button type="submit" [disabled]="!eventLogForm.valid" class="btn btn-default">Save</button>
<button class="btn" (click)="cancel()">Cancel</button>
</div>
</form>
結果-Create
結果-Edit
結果-Delete
下一篇我們再來看看如何實現Paging
參考
Angular 6 Forms Tutorial Example From Scratch
Angular 6 - Reactive Forms Validation Example
Reactive Forms in Angular: Dynamically Creating Form Fields With FormArray
Angular 6 Date format MM/dd/yyyy in reactive form
Angular Tips: Formatting Dates with a Custom Date Pipe (dd/MM/yyyy)
RxJS 6: What's new and what has changed?
Angular 6 RxJS 6 Tutorial & Example
RxJs Error Handling: Complete Practical Guide
Bug with Angular-Cli 6 : "Unknown option: '--extractCss'"
Angular Datepicker – Exploring Bootstrap (Part 3)