iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 5
1
Modern Web

Angular 元件庫 NG-ZORRO 基礎入門系列 第 5

[Angular 元件庫 NG-ZORRO 基礎入門] Day 05 - 待辦事項 + Form

前言回顧

昨天我們開發了第一個小專案:待辦事項,經過簡單的操作,我們完成了待辦事項的簡單展示,結合例項學習了 nz-table 元件的使用方式,儘管沒有涉及到全部屬性,但是我們已經可以讓一個 table 元件正常工作了。

今天我們會繼續對 待辦事項(TODO)進行優化,補全 建立任務修改任務刪除任務 等操作。

開始之前同樣地,請大家先下載 github 程式碼啟動後開啟 http://localhost:4200 預覽

$ git clone https://github.com/simplejason/ng-zorro-ironman2020.git
$ cd ng-zorro-ironman2020 && npm i
$ ng serve

待辦事項

功能預覽

我們今天需要完成建立、修改、刪除操作,先來看一下預覽圖
https://img.alicdn.com/tfs/TB1WxvmfXP7gK0jSZFjXXc5aXXa-2876-1350.gif

Form 元件

上文我們已經完成了顯示待辦事項的列表,想必大家還記得昨天我們在頁面上留了一個 新增任務 的按鈕,現在就讓我們來實現這個功能。既然是建立,我們就決定使用 form 元件來實現,NG-ZORRO 也為我們提供了改元件 nz-form

表單排列方式

  • 水平排列:標籤和表單控制元件水平排列;(預設)
  • 垂直排列:標籤和表單控制元件上下垂直排列;
  • 行內排列:表單項水平行內排列。

最簡結構

<form nz-form>
  <nz-form-item>
    <nz-form-label [nzSpan]="6" nzFor="email">E-mail</nz-form-label>
    <nz-form-control [nzSpan]="14">
      <input nz-input name="email" type="email" id="email">
    </nz-form-control>
  </nz-form-item >
</form>
  • nz-form-item:表單項,用於區分表單中不同的區域,包含表單域和表單標籤(可選)
  • nz-form-label:表單標籤,用於標示當前表單項的內容,可選
  • nz-form-control:表單域,表單一定會包含表單域,表單域可以是輸入控制元件,標準表單域,標籤,下拉選單,文字域等

https://ithelp.ithome.com.tw/upload/images/20190906/20112829yjVHnW3fXN.png

form 元件同樣遵循 ant design 設計規範,對於錯誤情況、佈局、校驗等都提供了相應的API,我們今天也會使用這些屬性來看看它的設計。

建立任務

暫時我們為了簡潔都是直接通過變數陣列的變化來展示,大家可以嘗試使用 localStorage 來儲存相應的資料。

Reactive Forms

為了便於開發,我們使用 Reactive Forms 來建立,我們之前給 task 任務設定了一個 interface 格式

export interface ITask {
  id: number;
  name: string;
  description: string;
  isDone?: boolean;
  deadline: Date;
}

這樣我們就很容易建立,進入到 todo.component.ts

export class TodoComponent implements OnInit {
    createForm: FormGroup;
    constructor(
    private fb: FormBuilder
  ) {
    this.createForm = this.fb.group({
      name       : [ null, [ Validators.required ] ],
      description: [ null ],
      isDone     : [ false ],
      deadline   : [ new Date() ]
    });
  }
}

我們在頁面上直接使用 nz-form 來建立一個表單,進入 todo.component.html 建立表單,這樣一個可輸入的表單就完成了。(stackblitz 線上程式碼

<form nz-form [formGroup]="createForm">
  <nz-form-item>
	<nz-form-control  nzErrorTip="請輸入名稱">
	  <nz-input-group nzCompact>
		<input class="form-name" type="text" nz-input placeholder="例如:今天八點前更新鐵人賽文章" formControlName="name"/>
		<nz-date-picker
						formControlName="deadline"
						nzFormat="MMMMd日 HH:mm"
						[nzShowTime]="{ nzFormat: 'HH:mm' }"
						[nzDisabledDate]="disabledDate"
						></nz-date-picker>
	  </nz-input-group>
	</nz-form-control>
  </nz-form-item>
</form>

可以看到我們很容易就建立了一個建立任務的表單,讓我們加上按鈕來美化一下,看一下效果
https://ithelp.ithome.com.tw/upload/images/20190906/20112829lgYmwwJwUl.png

對應的建立任務事件也很容易書寫

addTask(): void {
  // 驗證form狀態
  for (const i in this.createForm.controls) {
	this.createForm.controls[ i ].markAsDirty();
	this.createForm.controls[ i ].updateValueAndValidity();
  }
  if (this.createForm.valid) {
	const newTask = {
	  ...this.createForm.getRawValue(),
	  id: new Date().getTime()
	};
	// 更新待辦陣列
	this.listOfTodoTasks = this.listOfTodoTasks.concat([ newTask ]);
	// reset after adding new task
	this.createForm.get('name').reset();
	this.nzMessageService.success('成功建立了一個任務,記得完成喔!');
  }
}

PS:我們之前說了,nz-form 支援錯誤提示,只需要我們在 nz-form-control 上新增 nzErrorTip 屬性即可實現錯誤提示,參考 這個示例 來感受一下。

修改任務

既然建立都完成了,我們自然需要修改任務,比如需要切換完成時間、任務名稱等等操作,在這裡我們採用 nz-drawer 抽屜元件,我們先來看一個 線上的簡單 demo

<button nz-button nzType="primary" (click)="open()">Open</button>
<nz-drawer
		   [nzClosable]="false"
		   [nzVisible]="visible"
		   nzPlacement="right"
		   nzTitle="Basic Drawer"
		   (nzOnClose)="close()"
		   >
  <p>Some contents...</p>
  <p>Some contents...</p>
  <p>Some contents...</p>
</nz-drawer>

這裡直接通過 nz-drawer 元件的 nzVisible 屬性來控制是否顯示抽屜元件,不過我並不打算使用這種建立方式,因為這會導致我們的 html 檔案包含大量的複雜程式碼,使用 NzDrawerService 來建立是個更好地方案,它可以接受一個 component 作為渲染模板,這樣我們可以放心地將修改表單模組單獨以一個獨立元件來維護。

先看一下我們當前程式碼是如何寫的(Github Commit),在 todo.component.ts 中,我們將 TaskDetailComponent 作為顯示模板,傳遞 task 屬性使 TaskDetailComponent 能接收到要修改的任務資料, TaskDetailComponent 中呼叫 NzDrawerRef.close(data) 方法即可傳遞任意資料回來,this.drawerRef.afterClose 這個 Observable 就可以正常訂閱資料回顯,我們可以在這裡做一些特殊的操作。

在這種寫法和上面直接使用 nz-drawer 效果是一模一樣的,只是這種方式更加可維護。

showEditTask() {
  this.drawerRef = this.nzDrawerService.create({
	nzTitle        : this.activatedTask.name,
	nzContent      : TaskDetailComponent,
	nzWidth        : 400,
	nzContentParams: {
	  task: this.activatedTask
	}
  });

  // 觸發關閉
  this.drawerRef.afterClose.subscribe(task => {
	if (task) {
	  this.listOfTodoTasks = this.listOfTodoTasks.map(v => {
		if (v.id === task.id) {
		  v = task;
		}
		return v;
	  });
	  this.cdr.markForCheck();
	  this.nzMessageService.success('成功更新了這個任務!');
	}
  });
}

https://img.alicdn.com/tfs/TB1RqnmfoT1gK0jSZFhXXaAtVXa-2876-1350.gif

刪除任務

因為我們沒有通過 API 方式來管理資料,所以目前都是直接使用 filter 等陣列操作來完成,有興趣的同學可以自行建立一個 localStorage 操作的 service 來嘗試一下。

總結 & 預告

實際上今天我們僅僅是初步講解了 nz-formnz-drawer 的使用方式,目前待辦事項結構也是比較簡單的 form 結構,現在我們還不需要使用太多複雜的表單結構,否則會使我們的專案程式碼十分冗餘和難以理解。新出現的 nz-date-picker 元件也會在下一章節詳細去介紹一下。

form 表單有很多值得關注的地方等到我們去探索,大家可以跟隨文章的進展逐步去接觸更加複雜也更加有意思的表單使用方式。

下一篇我們會繼續來完善待辦事項,我們會給待辦任務新增更多的屬性來讓這個專案豐富起來。

相關資源


上一篇
[Angular 元件庫 NG-ZORRO 基礎入門] Day 04 - 待辦事項 + Table
下一篇
[Angular 元件庫 NG-ZORRO 基礎入門] Day 06 - 待辦事項 + 雙向繫結
系列文
Angular 元件庫 NG-ZORRO 基礎入門30

尚未有邦友留言

立即登入留言