表單實作與 Angular 筆記 - FormArray 表單實作差不多,有些部分就不贅述,僅記錄 API 操作的部分。
資料
本次範例使用下方資料,已經建立成 db.json
,並也啟用了 json-server
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| { "posts": [ { "name": "提姆", "height": 175, "id": 1 }, { "id": 2, "name": "lena", "height": 160 }, { "id": 3, "name": "eda", "height": 155 }, { "id": 4, "name": "mia", "height": 170 } ] }
|
建立 API 方法
- 在
service
資料夾下建立一個 API 資料夾,裡面建立一個 data.service.ts
。
- 定義一個
options
為任意型別,並制定好 header
要接收的格式。
mainUrl
的值是從 environment
中取得的,Angular 筆記 - Router 路由實作串接 API有提到過。
- 定義各種方法的 API,方法如註解所示。
data.service.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| options: any; mainUrl: string = environment.apiUrl; constructor(private http: HttpClient) { this.options = { headers: new HttpHeaders({ 'content-type': 'application/json', }), }; }
run() { console.log('service run'); }
getAllData(): Observable<PersonModal[]> { return this.http.get<PersonModal[]>(`${this.mainUrl}/posts`); }
getData(): Observable<PersonModal[]> { return this.http.get<PersonModal[]>(`${this.mainUrl}/posts/1`); }
insertData(request: PersonModal) { return this.http.post(`${this.mainUrl}/posts`, request, this.options); }
updateData(request: PersonModal, id: number) { return this.http.put(`${this.mainUrl}/posts/${id}`, request, this.options); }
deleteData(id: number) { return this.http.delete(`${this.mainUrl}/posts/${id}`, this.options); }
|
串接 API
先完成輸入框的部分,
html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <form [formGroup]="form"> <label> <span>名稱:</span> <input formControlName="name" type="text" /> </label> <label> <span>身高:</span> <input formControlName="height" type="text" /> <span>cm</span> </label>
<button type="button" class="btn btn-green" (click)="insertData()"> 新增 </button> <button type="button" class="btn btn-orange" (click)="submitData()"> 修改 </button> </form>
|
再把要呈現出清單的內容也寫出來,並把預設的欄位寫好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div class="title"> <h2>清單列表</h2> </div> <ul *ngFor="let item of lists"> <li> <span> 名稱: {{ item.name }} </span> <span> 身高:{{ item.height }}cm </span>
<button class="btn btn-orange" (click)="editData(item.id, item.name, item.height)" > 編輯 </button> <button class="btn btn-red" (click)="deleteData(item.id)">刪除</button> </li> </ul>
|
建立表單
建立表單的初始值。
list.component.ts
1 2 3 4 5 6 7 8 9 10 11
| creatForm() { this.form = this.formBuilder.group({ id: null, name: ['', Validators.required], height: ['', Validators.required], }); this.form.get('name').valueChanges.subscribe((res) => { console.log('value:', res); }); }
|
引入 AJAX 方法
將 data.service.ts
引入到建構式中。
1 2 3 4
| constructor( private formBuilder: FormBuilder, private dataSvs: DataService ) {}
|
get 取得所有與單一資料
取得所有資料與取得單一資料的方法幾乎一樣,只是使用方法不同,詳細內容可以參照上方 data.service.ts
的內容。
取得所有資料
使用一個 getAllData
的方法把資料存起來,並且在 ngOnInit
時呼叫,把資料渲染在畫面上。
1 2 3 4 5 6 7 8 9 10 11 12
| ngOnInit(): void { this.creatForm(); this.getAllData(); }
getAllData() { return this.dataSvs.getAllData().subscribe((res) => { this.lists = res; }); } }
|
delete 刪除當筆資料
- 在顯示資料清單中,在每一筆資料後方新增一個刪除按鈕,並綁定一個點擊事件。
- 點擊後會刪除所觸發的那一筆資料,並從資料庫刪除。
list.component.html
因為要刪除該筆資料,所以在刪除方法中帶入該資料的 id
,就可以把自己那筆資料刪除。
1 2 3 4 5 6 7
| <ul *ngFor="let item of lists"> <li> <span> 名稱: {{ item.name }} </span> <span> 身高:{{ item.height }}cm </span> <button class="btn btn-red" (click)="deleteData(item.id)">刪除</button> </li> </ul>
|
list.component.ts
刪除的方法帶入 id
參數,dataSvs
的刪除方法也接收到此 id
後,就會把該筆刪除,並重新呼叫 API。
1 2 3 4 5 6 7
| deleteData(id) { return this.dataSvs.deleteData(id).subscribe((res) => { console.log(res); this.getAllData(); }); }
|
post 新增資料
- 在輸入框輸入資料。
- 按下確認鍵後把輸入框的值傳給
db.json
中。
list.component.html
給予一個點擊事件按鈕,因為按鈕會預設為 submit
,所以要給予 button
的 type
為 button
,才不會因為按下 enter
就送出了。
1
| <button type="button" class="btn btn-green" (click)="insertData()">新增</button>
|
list.component.ts
- 使用
dataSvs
寫好的 post
方法 inserData
,並且把要傳送的物件格式寫在方法中。
- 傳送後重新呼叫 API 與清空表格。
1 2 3 4 5 6 7 8 9 10 11
| insertData() { this.dataSvs .insertData({ name: this.form.value.name, height: this.form.value.height, }) .subscribe((res) => { this.getAllData(); this.reset(); }); }
|
edit 編輯資料
這個方法與串接 API 方法無直接關係,但也滿值得紀錄一下。
list.component.html
與刪除方法類似,但這次要把有用到欄位用參數帶入 editData
方法中。
1 2 3 4 5 6 7 8 9 10 11 12 13
| <ul *ngFor="let item of lists"> <li> <span> 名稱: {{ item.name }} </span> <span> 身高:{{ item.height }}cm </span>
<button class="btn btn-orange" (click)="editData(item.id, item.name, item.height)" > 編輯 </button> </li> </ul>
|
list.component.ts
使用 form
本身的 patchValue
方法把欄位帶入對應屬性的值中。
1 2 3 4 5 6 7
| editData(id: number, name: string, height: number) { this.form.patchValue({ id: id, name: name, height: height, }); }
|
put 更新檔案
- 這邊是編輯完後點擊
submitData
按鈕事件。
- 使用的是包裝後的
put
方法:updateData()
。
list.component.html
1 2 3
| <button type="button" class="btn btn-orange" (click)="submitData()"> 修改 </button>
|
list.component.ts
- 因為修改送出並不會取到該筆
id
,所以另外在外面宣告一個 id
的變數,型別為 number
。
- 讓
id
變數儲存這個表單的 id
。
- 使用
dataSvs
中的 updateData
方法,並把要送出的物件格式放在參數的位置中,並給予對應的 id
欄位。
- 完成後重新呼叫 API 與清空輸入框。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| submitData() { this.id = this.form.getRawValue().id; this.dataSvs .updateData( { name: this.form.value.name, height: this.form.value.height, }, this.id ) .subscribe(() => { this.getAllData(); this.reset(); }); }
|