iT邦幫忙

2024 iThome 鐵人賽

DAY 5
0

前一篇文章我們找到了專案的路由架構並找到了’product-list’,本篇文章要從ProductListComponent開始建立元件之間的關係。

製作第一份系統架構圖(前端角度)

3. 從前端專案開始繪製組件

在Angular的世界中,元件主要可以跟以下項目建立關係:

  1. 其他元件
  2. service
  3. 路由
  4. pipe
  5. directive

本章我們主要討論元件、Service、路由,其中路由與元件之間的關係我們已經聊過,接著我們來看元件與其他元件之間的關係。

元件之間主要可以透過以下方式互動:

1. 輸入輸出屬性(@Input 和 @Output)

  • @Input:用於父元件向子元件傳遞資料。父元件可以通過在子元件的 HTML 標籤上綁定屬性來設定子元件的 @Input 屬性。
  • @Output:用於子元件向父元件傳遞事件。子元件可以定義一個 @Output 屬性,通常是一個 EventEmitter 實例,父元件可以監聽該事件來獲取子元件的狀態或回應子元件的操作。
// 子元件
@Component({
  selector: 'child-component',
  template: `<button (click)="notifyParent()">Notify Parent</button>`
})
export class ChildComponent {
  @Input() childData: string;
  @Output() childEvent = new EventEmitter<string>();

  notifyParent() {
    this.childEvent.emit('Message from Child');
  }
}

// 父元件
@Component({
  selector: 'parent-component',
  template: `
    <child-component [childData]="parentData" (childEvent)="handleEvent($event)"></child-component>
  `
})
export class ParentComponent {
  parentData = 'Data from Parent';

  handleEvent(message: string) {
    console.log(message);
  }
}

2. ViewChild 和 ViewChildren

  • @ViewChild:用於在父元件中取得子元件的實例。它允許父元件直接存取子元件的屬性和方法。
  • @ViewChildren:用於取得多個子元件的實例集合。
// 子元件
@Component({
  selector: 'child-component',
  template: `<p>Child Component</p>`
})
export class ChildComponent {
  public childMethod() {
    console.log('Child Method Called');
  }
}

// 父元件
@Component({
  selector: 'parent-component',
  template: `<child-component></child-component>`
})
export class ParentComponent implements AfterViewInit {
  @ViewChild(ChildComponent) childComponent: ChildComponent;

  ngAfterViewInit() {
    this.childComponent.childMethod();
  }
}

回到範例,我們主要要找的就是,HTML 裡有無 <app-*> 標籤,TS 檔案裡有無 @ViewChild 或 @ViewChildren,且同時,我們所在的 component 本身有沒有被其他人所引用。
https://ithelp.ithome.com.tw/upload/images/20240919/20169487mF0prvOjJq.png
https://ithelp.ithome.com.tw/upload/images/20240919/201694876JGJifIblM.png

可以發現範例很單純,只有使用了 ProductCardComponent 作為子元件,不過切記,我們所在的 component 本身也有可能被其他人所引用。
https://ithelp.ithome.com.tw/upload/images/20240919/20169487RlXu9FJDkb.png

調查完畢後,將我們的架構圖更新,並且按照資料夾結構區分檔案,並補上 component 的用途。
https://ithelp.ithome.com.tw/upload/images/20240919/20169487hBSGhBMW84.png

Component 的重點整理:

  1. 找子元件
  2. 找 ViewChild / ViewChildren
  3. 找 component 本身有無被他人引用

最後我們來講 Service,在 Angular 中,服務(Service)是一個用於封裝共享邏輯和資料的類別,通常透過依賴注入(Dependency Injection)進行使用。服務主要可以與以下項目互動:

1. 元件(Components)

  • 依賴注入:元件可以透過依賴注入使用服務,從而共享資料或邏輯。這是服務與元件互動的最常見方式。
  • 資料共享:不同元件可以使用同一個服務來共享狀態或資料。例如,表單資料、使用者狀態、設置等。
  • 業務邏輯:將複雜的業務邏輯從元件中抽離到服務中,保持元件的簡單和單一職責。
@Injectable({ providedIn: 'root' })
export class DataService {
  private data = new BehaviorSubject<string>('Initial Data');
  currentData = this.data.asObservable();

  updateData(newData: string) {
    this.data.next(newData);
  }
}

// 元件中使用
@Component({ /*...*/ })
export class SomeComponent {
  constructor(private dataService: DataService) {}

  update() {
    this.dataService.updateData('New Data');
  }
}

2. 其他服務(Services)

  • 服務之間的互動:一個服務可以注入另一個服務,從而組合多個服務的功能。例如,一個身份驗證服務可能需要注入一個 HTTP 服務來進行伺服器請求。
  • 共享資料和邏輯:服務可以利用其他服務來擴展其功能,實現更複雜的邏輯。例如,日誌服務可以被多個服務注入,用於記錄日誌。
@Injectable({ providedIn: 'root' })
export class AuthService {
  constructor(private http: HttpClient) {}

  login(credentials: any) {
    return this.http.post('/api/login', credentials);
  }
}

@Injectable({ providedIn: 'root' })
export class UserService {
  constructor(private authService: AuthService) {}

  authenticateUser(credentials: any) {
    return this.authService.login(credentials);
  }
}

3. HTTP 客戶端(HttpClient)

  • 伺服器通訊:服務可以使用 Angular 的 HttpClient 來與遠端伺服器進行通訊,執行 HTTP 請求(GET、POST、PUT、DELETE 等)。
  • 資料獲取和儲存:服務通常用於從伺服器獲取資料,並將資料提供給元件使用。
@Injectable({ providedIn: 'root' })
export class ApiService {
  constructor(private http: HttpClient) {}

  fetchData() {
    return this.http.get('/api/data');
  }
}

可以發現 Service 的應用層面非常廣,上述也只是其中幾種用法,所以不建議一開始從 Service 當作切入點,會很容易找到頭暈。

雖然 Service 的用途如此廣大,但我們現在要 Focus 的是 ProductList 這個 component,換言之,我們要看的就是 ProductListComponent 與那些 Service 進行互動,並且按照前述的繪圖方式記錄下來。
https://ithelp.ithome.com.tw/upload/images/20240919/201694872TjYcRaLNL.png

可以發現範例中,ProductList 使用了 ProductBusinessLogicService,先不用急著閱讀 Service 內的邏輯,先專注在我們的目標 ProductListComponent 上,這樣在一開始理解專案時比較不容易混亂。
接著一樣更新圖表。
https://ithelp.ithome.com.tw/upload/images/20240919/20169487ueynKN9Np2.png

接著其實就是重複上述步驟,一次以一個 component 或是 Service 為目標搭配資料夾結構,逐一把圖表填滿,重點放在檔案和檔案之間的階層和關係上。


下一篇文章我們會補上前端專案與外部依賴和 API 的關聯。


上一篇
# 前端角度的系統架構圖(二)
下一篇
# 前端角度的系統架構圖(四)
系列文
轉生成前端工程師後,30步離開新手村!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言