0%

Angular 筆記 - form 表單基礎實作

angular

form 表單不管是前台填寫報名表還是後台表單填寫都很常見到,而 Angular 也把 form 做了更便利性的包裝,這次學習到便將其記錄起來。

form 起手式

Angular 包含了許多函式庫,form 表單便是其中之一,且官方文件還特別拉出一部分的篇幅來教學,可見表單元件的重要性。

引入表單相關模組

先在 app.module.ts 引入表單相關模組,

  • FormsModule
  • ReactiveFormsModule

再新增一個 form 資料夾裡面新增一組 form.component,form 有提供許多元件,起手式為:

  1. 先在 form.component.ts 檔案中新增 name 變數。
  2. 使其變數來儲存 formControl 的實體,並且給予初始值為空值。

form.component.ts

1
name = new FormControl("");

form.component.html

在 HTML 中輸入下方程式碼,

1
2
3
4
<label>
Name:
<input type="text" [formControl]="name">
</label>

說明:

  1. 使用屬性繫結並使用 formControl 的實體,並使用剛剛新增的 name 變數。

建立表單

表單模組還有一個元件為 FormBuilder,用來建立表單用,因上方的表單只是新增出來實體,但沒有辦法做到資料互動傳達。

在建構是中建立一個私有方法為 formBuilder 的自訂義變數,並用來存 FormBuilder 的元件。

1
constructor(private formBuilder: FormBuilder) {}

我想要在 DOM 產生前就建立好表單,所以在生命週期初始的時候就建立此內容,

1
2
3
ngOnInit(): void {
this.createForm();
}

並且把要建立的內容寫在函式內,

1
2
3
4
5
6
7
8
9
10
11
createForm() {
this.form = this.formBuilder.group({
formName: [{ value: '1111', disabled: true }, Validators.required],
firstName: ['', Validators.required],
lastName: ['', Validators.required],
});
// 驗證表單與觀察表單變數的狀態,類似 vue watch
this.form.get('formName').valueChanges.subscribe((res) => {
console.log('value:', res);
});
}

說明:

  1. Angular 要新增物件的語法為 this.XXXXX.group({物件屬性:值}),以上方為例,就是在裡面建立了三個屬性。
  • formName
  • firstName
  • lastName
  1. 完成後給予值,用一個陣列包起來,第一個欄位為初始值,後面是使用驗證器與條件。
  • formName:初始值為一個物件,其屬性為 value,其值為字串 1111,另一個屬性為預設是否為 disabled,條件為必填。
  • firstNamelastName 條件相同,初始值為空值,也都為必填。

表單群組化

有發現到新增了三個欄位,也就是表單會有三欄,此時 Angular 把多個欄位合併管理,使用一個指令為 formControlName,其功能是將現有 FormGroup 中的 FormControl 與一個表單控制元件進行同步。

HTML 中原本是用屬性繫結的方式也改成此指令代替,其值為剛剛新增的物件屬性。
form.component.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="p-field">
<label>
<span>formName</span>
<input type="text" pInputText formControlName="formName" />
</label>
</div>
<div class="p-field">
<label>
<span> firstName </span>
<input type="text" pInputText formControlName="firstName" />
</label>
</div>
<div class="p-field">
<label>
<span> lastName </span>
<input type="text" pInputText formControlName="lastName" />
</label>
</div>

既然三人成伍,也有一個 formGroup 的指令可以用,html 最外層再給予一個 form 標籤,並加上 [formGroup] = "form" 的屬性,來取得整個表單的值。

form.component.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<form [formGroup]="form">
<div class="p-field">
<label>
<span>formName</span>
<input type="text" pInputText formControlName="formName" />
</label>
</div>
<div class="p-field">
<label>
<span> firstName </span>
<input type="text" pInputText formControlName="firstName" />
</label>
</div>
<div class="p-field">
<label>
<span> lastName </span>
<input type="text" pInputText formControlName="lastName" />
</label>
</div>
</form>

form.component.ts 也在 form 變數中加上其屬性。

form.component.ts

1
form: FormGroup;

取得表單的值

使用一個按鈕並給予事件 getFormValue(),動態取得表單的控制元件值。

1
<p-button (click)="getFormValue()">動態取得表單的控制元件值 </p-button>

事件中內寫入要查看的內容,

form.component.ts

1
2
3
4
5
6
7
8
getFormValue() {
console.log('control:', this.formName);
console.log(this.formName.value);
console.log('form:', this.form);
console.log('value:', this.form.value); //無法取得 disabled 的值
console.log('getRawValue:', this.form.getRawValue()); //可取得 disabled 的值
console.log('valid:', this.form.valid);
}

更新表單元件值

form.component.ts

1
2
3
4
updateFormValue() {
this.form.get('firstName').setValue('更新全部表單元件值成功');
this.form.get('lastName').patchValue('更新部分表單元件值成功');
}

有兩種方法可以取得更新,setValue 跟 patchValue。
setValue:若欄位與 interface 屬性不同則會跳錯。

patchValue:若欄位有找到相符的就可以更新。

重新設定表單內容

這個比較單純,就是令表單使用 reset 方法。

1
2
3
resetForm() {
this.form.reset();
}

Demo: https://stackblitz.com/edit/angular-ivy-fkqhhu?embed=1&file=src/app/app.component.ts