iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 19
1
Modern Web

從零開始的點餐系統,Google好棒棒系列 第 19

[Day19] Angular 主要概念 - Component 實作(2)

本篇延續上篇的實作 components ,用商家管理的功能來說明 Container components 與 Presentational components 之間用@Input() @Output() 溝通

產生出商家管理所需的 components

與上一篇大同小異,不一樣的地方是在這裡新增了 models 的資料夾與 model 的檔案 (第 3、16、17 行),需要 model 是因為我們實作的功能會有有關商家的 Data,我們要定義商家這個型別有什麼屬性,讓我們在開發上能用到 TypeScript 帶來的好處。

cd ./merchant
touch index.ts
mkdir components containers models
cd ./containers
ng g c merchant-list
cd ../components
ng g c merchant-item
ng g c merchant-edit
cd ../models
ng g class merchant --type=model

將 merchant-list component 與 merchant 模組匯出與上一篇類似,這裡就不一一說明,如果不太知道怎麼做可以看今日程式碼

再來是修改一下 app.component.html 檔案,把 app-merchant-list 加上去

<app-nav class="mat-elevation-z6"></app-nav>
<app-layout>
  <app-merchant-list></app-merchant-list>
</app-layout>

定義 Merchant 型別

這裡為 Merchant 的 class 定義裡了這些屬性,分別是識別碼、名稱、商家地址、商家電話、商家網站、商家 LOGO

export class Merchant {
  id: string;
  name: string;
  adress: string;
  phone: string;
  website: string;
  logo: string;
}

實作 merchant-list component

依照剛剛在產生這 component 放的資料夾位置,大家應該可以猜到他會被定義成一個 Container component。在這我會先給他儲存狀態與操作狀態的職責(將來這個狀態會交給 service),然後給這個 class 一些屬性與方法,分別為 merchant(各個商家的資料)、openEditModal(打開編輯商家資訊的跳窗)、createMerchant(新增新增商家)、updateMerchant(更新商家的資訊)、deleteMerchant(刪除商家),這次只先實作刪除商家。

// ... 省略
export class MerchantListComponent implements OnInit {
  merchants: Merchant[] = fakeMerchants;

  constructor() {}

  ngOnInit(): void {}

  openEditModal(mode, merchantId?): void {
    console.log('mode', mode);
    console.log('id', merchantId);
  }

  createMerchant(merchant): void {}

  updateMerchant(merchant): void {}

  deleteMerchant(merchantId): void {
    this.merchants = this.merchants.filter(
      (merchant) => merchant.id !== merchantId
    );
  }
}

merchant-list.component.html 中,因為畫面要顯示每個商家個別的資訊,所以要加入 app-merchant-item 這個 component,並用 Property binding (第 4 行)與 Event binding (第 5、6 行)的方式讓 components 溝通 (稍後再說明如何實作)

第 2 行的 *ngFor 為內建的 Structural directives,會依照模板(第 2~8 行)與屬性綁定的數據 (merchants) 建立一到多個物件

<div class="category-list">
  <div *ngFor="let merchant of merchants" class="category-list-item">
    <app-merchant-item
      [merchant]="merchant"
      (openModal)="openEditModal('edit', $event)"
      (deleteItem)="deleteMerchant($event)"
    ></app-merchant-item>
  </div>
  <div class="category-list-item add-button" (click)="openEditModal('create')">
    <p>+ 新增店家</p>
  </div>
</div>

實作 merchant-item component

merchant-item 是一個 presentational component ,他的職責在顯示 UI 與把使用者事件傳出去,在他的 class 雖然有 editMerchant、deleteMerchant 的兩個方法,實際上沒有實作的邏輯,還是藉由事件的方式把 merchantId 傳出去(第 4、5、12、16 行);而這裡的 merchant 屬性(第 3 行)則是由父 component 傳值進來的。 html 與 css 這邊就不再多說明了,主要是一些畫面呈現與使用 material 套件的技巧。

// ... 省略
export class MerchantItemComponent implements OnInit {
  @Input() merchant: Merchant;
  @Output() editItem = new EventEmitter<string>();
  @Output() deleteItem = new EventEmitter<string>();

  constructor() {}

  ngOnInit(): void {}

  editMerchant(merchantId?: string): void {
    this.editItem.emit(merchantId);
  }

  deleteMerchant(merchantId: string): void {
    this.deleteItem.emit(merchantId);
  }
}

結語

components 的概念就介紹到這裡,這是今天的程式碼。題外話,對於完全沒接觸過 Angular 的人來說可能會有點難消化,不過說實在,Angular 從零開始教學的類似主題已有很多厲害的大大整理出來過了,這邊想透過另一種方式來介紹 Angular 的各個角色。再來下一篇會介紹 service 是做什麼用的。


上一篇
[Day18] Angular 主要概念 - Component 實作(1)
下一篇
[Day20] Angular 主要概念 - Services 與依賴注入
系列文
從零開始的點餐系統,Google好棒棒30

尚未有邦友留言

立即登入留言