4-2.Angular 入門教學 - 將API部分獨立成一支Service

Angular 入門教學

影片講解


這篇要來實作我們一路熟悉的todo專案的service拆分

那一開始我們先幫service建一個資料夾

接著打上指令新增一個service,那這邊因為是專門放api的service所以取名為todo-api

ng g s todo-api

接著把我們有關api的程式片段都給搬到這邊來,那目的有二

  1. 單一職責:就都是api相關的程式
  2. 共用性:未來有可能其他地方也會用到這些api

todo-api.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Todo } from '../@models/todo.model';

@Injectable({
  providedIn: 'root'
})
export class TodoApiService {
  private url = '/api/todo2_16';

  constructor(private http: HttpClient) { }

  取得資料() {
    return this.http.get<Todo[]>(this.url);
  }

  新增(value: Todo) {
    return this.http.post<Todo>(this.url, value);
  }

  修改(value: Todo) {
    return this.http.put(`${this.url}/${value.TodoId}`, value);
  }

  刪除(value: Todo) {
    return this.http.delete(`${this.url}/${value.TodoId}`);
  }

  全部狀態統一(value: boolean) {
    return this.http.put(`${this.url}/Status/${value}`, null);
  }

  刪除已完成事項() {
    return this.http.delete(`${this.url}/clearCompleted`);
  }
  
}

那中文的部分,如果有看過我ASP.NET Core API的人,就知道我很喜歡在程式裡寫中文

只要不會出問題的地方,我都會寫中文命名,那這個地方寫中文,我目前沒有遇到什麼bug

但有些人可能不認同中文,那就當作沒看到XD

接著我們要改寫我們本來在AppComponent中相關的程式

app.component.ts

//原來的HttpClient已經不用了,所以可以拿掉,換成我們今天的主角
constructor(private todoApiService: TodoApiService) { }

getData() {
  //改這邊
  this.todoApiService.取得資料().subscribe(data => {
    this.todoDataList = data;
    this.todoDataList.forEach(data2 => {
      data2.CanEdit = true;
      data2.Editing = false;
    });
    this.checkToggleAllBtn();
  });
}

add() {
  const seqno = new Date().getTime();
  const todo: Todo = new TodoClass(this.todoInputModel, false, seqno);
  this.todoDataList.push(todo);
  //改這邊
  this.todoApiService.新增(todo).subscribe(data => {
    this.todoDataList.forEach(data2 => {
      if (data2.Seqno === seqno) {
        data2.TodoId = data.TodoId;
        data2.CanEdit = true;
      }
    })
  });
  this.todoInputModel = '';
}

update(item: Todo) {
  //改這邊
  this.todoApiService.修改(item).subscribe();
  item.Editing = false;
}

clickCheck(item: Todo) {
  item.Status = !item.Status;
  //改這邊
  this.todoApiService.修改(item).subscribe();
  this.checkToggleAllBtn();
}

delete(item: Todo) {
  //改這邊
  this.todoApiService.刪除(item).subscribe();
  this.todoDataList = this.todoDataList.filter(data => data !== item);
}

toggleAll() {
  this.toggleAllBtn = !this.toggleAllBtn;
  this.todoDataList.forEach(data => {
    data.Status = this.toggleAllBtn;
  });

  //改這邊
  this.todoApiService.全部狀態統一(this.toggleAllBtn).subscribe();
}

clearCompleted() {
  //改這邊
  this.todoApiService.刪除已完成事項().subscribe();
  this.todoDataList = this.todoActive;
}

總共改了以上七個地方

那改完一定會有人覺得,似乎沒有切分出去的必要,因為就程式面來看

程式本身並沒有精簡的感覺,call來call去也覺得特別麻煩

但前面也就說了,這樣切出去的目的是單一職責跟共用性

也就是說幫助的地方會是在後續維護的時候才會體現出來

像是以後程式一多,如果api的網址或傳的值有所改變,我們可以很快多鎖定這個service下去改

就不用在原來的AppComponent找尋那些散落的http的程式片段

其二就是或許會有其他地方會用到相同的api,所以我們就先獨立出來

那接著執行一下程式,看看改完有沒有一樣正常運作

沒問題的話,恭喜,算是踏出了成功第一步

想看操作流程,可以看影片

範例檔:下載




Copyright © 凱哥寫程式 2022 | Powered by TalllKai ❤