iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
Modern Web

從0開始的的Angular站台架設-Stnadalone 系列 第 12

D11 立即反應的NgModel與Form表單資料管理

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20230922/20162031lHD84bWc35.png

昨天我們簡單說了[Input]與(Output)的資料拋接球與雙向綁定資料流流程。

今天我們來講講同樣是雙向綁定資料中重要的腳色,NgModel與Form的表單管理


NgModel可以說是NG I/O 銜接至Form之間的一個小小的...示範?

它本身的實作其實是同時結合了Input-(ngModel)與Output-[ngModelChange]兩者,在單一component中我只要進行"xxx"的Input的裝飾器綁定並同時開通一個"xxxChange"的Output管道就可以在這個元件中建構屬於自己的ngModel,而Angularn所進行的Forme也是在此基礎開始複雜化與成長

稍後我們可以透過在之前所說的插植法來看看我們的資料是不是被及時儲存在我們的變數裡了,現在先來看看要怎麼使用ngModel以及談談我什麼後會使用他。

ngModel 首先是Angular中的一個指令,通常與表單控件(例如input、textarea、select等)一起使用,以實現雙向數據綁定。當表單控件的值發生變化時,相應的數據模型也會同步變化,反之亦然。

我們當然也可以透過原生JS的input去取得value然後變更宣告變數值再把他放在html上...。

好麻煩...不斷氣講這句話真的有夠麻煩的

所以當我進行ngModel的使用時通常是希望可以立即處理使用者的資料需求,例如在搜尋欄輸入字詞之後立即提供下拉式選單供使用者進行選取的autoComplete功能,又或者及時檢驗使用者輸入的資料是否已經達到我們所偵測的關鍵字或是限制以此來進行後續事件的觸發或預載入所需資訊,選擇的日期的時長是不是已經超出時長限制了呢? 音樂會想要的位置是不是已經被訂走了呢? 使用者是不是輸入不雅字眼,我直接幫他過濾好了

同時ngModel所綁定的東西可以非常的自由並根據ngFor迴圈進行同一宣告變數的資料異動,在有一些情境我們可能會需要動態的生成表單並即時訂閱他的資料變化,根據變化內容去進行後續的渲染或是效果呈現,這時候我們就可以透過宣告一個Object或是Array在裡面動態新編刪我的當前資料

<input [(ngModel)]="userNameStahsList[index]" name="username" />

這個方法很好的幫我避開了Form表單在動態生成與訂閱後續麻煩,因為Form表單管理中的動態生成FormGroup與FormControl的生成是如下程式碼


<form [formGroup]="myForm">
  <div formArrayName="items">
    <div *ngFor="let item of myForm.get('items').controls; let i = index" [formGroupName]="i">
      <!-- 在這裡顯示和互動表單控件 -->
      <input formControlName="name" placeholder="Item Name">
    </div>
  </div>
</form>

動態新刪則是如下


const newItem = new FormGroup({
  name: new FormControl('New Item Name')
});

(this.myForm.get('items') as FormArray).push(newItem);

只能說在一些想要簡單快速使用的資料上我會更加傾向使用ngModel去做資料的處理

既然都說到了Form了,接下來就讓我們來說說Angular對於Form的機制處理吧


在Angular中,表單是一個常見的用於收集和處理用戶輸入數據的功能。Angular 提供了一個強大的表單模組,稱為 FormsModule,它使我們能夠輕鬆地創建和處理表單。

聽起來是不是很像我們想像中的FormGroup? 接下來是不是就可以直接用在我們的component.ts中直接使用FormGroup以及各式各樣酷炫的功能了?

https://ithelp.ithome.com.tw/upload/images/20230922/20162031jd1nGc58cL.png

這邊的FormsModule指的是[(ngModel)]這個東東,還不是我們在各種stackoverflow中看到的各種神仙範例

實際上我們常見的FormBuild<=>FB 、FormGroup以及FormControl都是在ReactiveFormsModule之中的。

FormsModule 基於模板驅動表單,使用 ngModel 指令來建立表單並實現數據綁定。它的主要思想是在模板中創建表單元素,然後使用指令來建立與組件類中變數的綁定。而ReactiveFormsModule 基於反應式編程原則,使用 RxJS 库來處理表單數據流。它的主要思想是在組件類中建立表單模型(FormGroup、FormControl),然後在模板中將表單控件(FormControl)綁定到組件類中的變數。所以我們會看到一堆的valueChange.subscribe()就是從這邊來的。

也因為如此,ReactiveForms使用 formControl 或 formControlName 指令來綁定單向數據流,我們需要明確控制表單數據的變化以及對其的反應。

另外必須要說的是,隨著Angular@14開始的Formcontrol強型別的實現,我們在驗證器所下的功夫可以少點了。
FormsModul主要通過html中既有的 required、minlength、maxlength 等屬性來實現驗證。而ReactiveFormsModule 提供更多的驗證選項,包括內置的驗證器(例如 Validators.required、Validators.email 等)以及自定義驗證器。這些驗證器可以更容易地定義和應用,並且更靈活。

ngModel我們已經看過程式碼了,我們接接下來就直接看看FB(formBuild from ReactiveFormsModule) 吧

  fb = inject(FormBuilder);
  userGenderForm = this.fb.group({
    IsMale: new FormControl<boolean>(false),
    IsFemale: new FormControl<boolean>(false),
    Remark: new FormControl<string>(''),
  });

我們可以透過初始化就進行FormBuild的宣告,來建置我們的FormGroup,同時FormGroup是可以嵌套下去的


 outerForm: FormGroup = new FormGroup({
    firstName: new FormControl('', [Validators.required]),
    lastName: new FormControl('', [Validators.required]),
    address: new FormGroup({
      street: new FormControl('', [Validators.required]),
      city: new FormControl('', [Validators.required]),
      zip: new FormControl('', [Validators.required, Validators.pattern(/^\d{5}$/)]),
    }),
  });

我們可以透過FormBuild建置一個放入複數FormControl或FormArray的FormGroup,並且FormGroup可以不斷的為所欲為、為所欲為、為所欲為、為所欲為、為所欲為、為所欲為的FormGroup嵌套下去

總之,選擇使用 FormsModule 還是 ReactiveFormsModule 取決於你的項目需求和個人偏好。對於簡單的表單,特別是原型和小型應用,FormsModule 可能更容易入門。對於複雜的表單,需要更多控制和彈性以及更強大的驗證,ReactiveFormsModule 更適合。有時,項目中也可以混合使用這兩種模組,根據具體的表單需求來選擇適當的方法。


上一篇
D10 川流不息的資料流 Input() and @Output()與他們的生命週期
下一篇
D12 局部還原Component至第三方套件所需依賴Module
系列文
從0開始的的Angular站台架設-Stnadalone 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言