NgForm學習筆記

從廢棄的 ngForm 選擇器遷移過來監聽表單提交設置更新選項NgForm與NgModelngModel[ngModel][(ngModel)]參考文獻javascript

NgForm 建立一個頂級的 FormGroup 實例,並把它綁定到一個表單,以跟蹤表單的聚合值及其驗證狀態。 html

官方文檔說明:java

只要你導入了 FormsModule,該指令就會默認在全部web

標籤上生效。你不須要再添加任何特殊的選擇器。

你能夠以 ngForm 做爲 key 把該指令導出到一個局部模板變量(如 #myForm="ngForm")。這是可選的,但頗有用。 來自本指令背後的 FormGroup 實例的不少屬性,都被複制到了指令自身,因此拿到一個對該指令的引用就可讓你訪問此表單的聚合值和驗證狀態, 還有那些用戶交互類的屬性,好比 dirtytouchedjson

若是須要,還能夠監聽該指令的 ngSubmit 事件,以便當用戶觸發了一次表單提交時獲得通知。發出 ngSubmit 事件時,會攜帶原始的 DOM 表單提交事件。app

在模板驅動表單中,全部 標籤都會自動應用上 `NgForm` 指令。 若是你只想導入 `FormsModule` 而不想把它應用於某些表單中,好比,要想使用 HTML5 驗證,你能夠添加 `ngNoForm` 屬性, 這樣標籤就不會在 上建立 NgForm 指令了。 在響應式表單中,則不須要用 ngNoForm,由於 NgForm 指令不會自動應用到 ` 標籤上,你只要別主動添加formGroup` 指令就能夠了。post

從廢棄的 ngForm 選擇器遷移過來

ngForm 元素選擇器的支持已經在 Angular v6 中廢棄,並將在 Angular v9 中移除。性能

之因此棄用它,是咱們要讓全部選擇器都跟其它核心 Angular 選擇器保持統一,而元素選擇器一般寫做中線格式。測試

已廢棄的寫法:ui

<ngForm #myForm="ngForm">
複製代碼

之後的寫法:

<ng-form #myForm="ngForm">
複製代碼

監聽表單提交

下面的示例顯示如何從「 ngSubmit」事件捕獲表單值。

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
    <h2>Listening for form submission</h2>

    <form  (ngSubmit)="onSubmit(f)" #f="ngForm" novalidate >
      <label>First Name: <input name="first" ngModel required #first="ngModel" /></label>
      <br>
      <label>Last Name: <input name="last" ngModel /></label>
      <br>
      <button>Submit</button>
    </form>

    <div>
      <p>First name value: {{ first.value }}</p>
      <p>First name valid: {{ first.valid }}</p>
      <p>Form value: {{ f.value | json }}</p>
      <p>Form valid: {{ f.valid }}</p>
    </div>

    <div [hidden]="!f.valid">
      <p>{{submitMessage }}</p>
    </div>
  `
,
})
export class SimpleFormComp {
  submitMessage = '';
  onSubmit(f: NgForm) {
    console.log(f.value);
    console.log(f.valid);
    this.submitMessage = '數據已提交';
  }
}
複製代碼

頁面測試:

設置更新選項

自 Angular5 以後,增長了這麼一個新特性:updateOn blur或submit

表單字段或整個表單新增了選項 updateOn,它可讓 Angular 僅在 blur 或 submit 事件時檢查有效性,而不是默認的變動事件,這有助於提升性能。

例如,給定一個模板驅動的表單,以下所示:

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
     <form #newUserForm="ngForm" (ngSubmit)="onSubmit(newUserForm)">

      <label for="user-name">User Name:</label>
      <input type="text" placeholder="User name"
             required maxlength="25" id="user-name"
             [(ngModel)]="userName" name="userName">

      <button type="submit" [disabled]="!newUserForm.form.valid">
        Register
      </button>
    </form>
  `
,
})
export class SimpleFormComp {
  onSubmit(f: NgForm) {
    console.log(f.value);  // { first: '', last: '' }
    console.log(f.valid);  // false
  }
}
複製代碼

頁面測試:

注意觀察 html 代碼中的 button 標籤,當開始在輸入框輸入內容時,button 標籤的 disabled 屬性馬上消失,通俗點講就是表單時刻都在作有效性檢查。

若是你如今想輸入內容,讓 Angular 僅在輸入觸發 blur 事件時才進行有效性檢查:

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
     <form #newUserForm="ngForm" (ngSubmit)="onSubmit(newUserForm)">

      <label for="user-name">User Name:</label>

      <input type="text" placeholder="User name"
          required maxlength="5" id="user-name"
          [(ngModel)]="userName" name="userName"
          [ngModelOptions]="{updateOn: 'blur'}" />

      <button type="submit" [disabled]="!newUserForm.form.valid">
        Register
      </button>
    </form>
  `
,
})
export class SimpleFormComp {
  onSubmit(f: NgForm) {
    console.log(f.value);  // { first: '', last: '' }
    console.log(f.valid);  // false
  }
}
複製代碼

頁面測試:

當輸入完數據以後,鼠標焦點事件改變以後,button 標籤纔會啓用。

對於上述對 input 標籤的修改,也能夠一次性對整個表單應用。

<form #newUserForm="ngForm"
      (ngSubmit)="onSubmit(newUserForm)"
      [ngFormOptions]="{updateOn: 'blur'}">

  ...
</form>
複製代碼

NgForm與NgModel

NgForm 中關於 NgModel 的使用有三種用法,分爲 ngModel、[ngModel]和[(ngModel)]。

ngModel

若是單獨使用 ngModel,且沒有爲其賦值的話,它會在其所在的 ngForm.value 對象上添加一個 property,此 property 的 key 值爲 ngModel 所在組件設置的 name 屬性的值:

<form #f="ngForm">
  <input type="text" ngModel name="firstField">
  <br>
  <span>{{ f.controls['firstField']?.value }}</span>
  <p>{{f.value | json }}</p>    //{ "firstField": "" }
</form>
複製代碼

單獨使用 ngModel 時,若是沒有爲 ngModel 賦值的話,則必須存在 name 屬性

[ngModel]

ngForm 中綁定的 property 的 key 爲 ngModel 所在組件設置的 name 屬性的值,value 值咱們能夠賦予默認值。此時須要使用單向數據綁定的格式了,也就是[ngModel]:

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
    <form #ff="ngForm">
      <input type="text" name="firstField" [ngModel]="model.firstField" placeholder='Input your userName' >
      <p>{{ff.value | json }}</p>
      <p>{{model | json}}</p>
    </form>
  `
,
})
export class SimpleFormComp {
    model = {
    firstField'hresh'
  };
}
複製代碼

頁面測試:

這裏咱們使用了單向數據綁定的特色,能夠爲 ngForm.value 添加一個帶有初始值的 property。

[(ngModel)]

上述的單向數據綁定在單純地提供初始值頗有用,不過老是有些場景須要將用戶輸入體如今咱們的 model 上,此時就須要雙向數據綁定了,也即[(ngModel)]:

import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector'example-app',
  template`
    <form #ff="ngForm">
      <input type="text" name="firstField" [(ngModel)]="model.firstField" placeholder='Input your userName' >
      <p>{{ff.value | json }}</p>
      <p>{{model | json}}</p>
    </form>
  `
,
})
export class SimpleFormComp {
    model = {
    firstField'hresh'
  };
}
複製代碼

頁面測試:

這裏咱們不只爲 ngForm.value 添加了一個帶有初始值的 property,還能實現 Model 和 View 層的聯動。

參考文獻

Angular 2 ngForm中的ngModel、[ngModel]和[(ngModel)]

[譯]Angular 5:升級和新功能的總結

相關文章
相關標籤/搜索