ng4中,有兩種方式去聲明一個表單
一:Template-Driven Forms - 模板驅動式表單 [引入FormsModule]
1.ngForm賦值 [可以方便的獲取表單的值]
<form #f='ngForm' novalidate (ngSumbit)='onSubmit(f)'>
<input type='text'
name='username'
[(ngModel)]='login.username'
required>
<div *ngIf='f.controls.username?.required' class='error'>
Name is required.
</div>
</form>
2.ngModel綁定 [ngModel會自動關聯表單控件name屬性,並使用該值作為ngForm對象的屬性名]
以下有三種寫法:
<input type='text' name='username' ngModel>
<input type='text' name='username' [ngModel]='login.username'>
<input type='text' name='username' [(ngModel)]='login.username'>
3.ngModel賦值 [可以操縱表單控件的事件]
<form #f='ngForm' novalidate (ngSumbit)='onSubmit(f)'>
<input type='text'
name='username'
[(ngModel)]='login.username'
#username='ngModel' (change)='changeName(username.value)' required>
<div *ngIf='username.error?.required && username.touched' class='error'>
Name is required.
</div>
</form>
4.驗證規則相關 [required/minlength/maxlength等]
<form #f='ngForm' novalidate (ngSumbit)='onSubmit(f)'> <input type='text' name='username' [(ngModel)]='login.username' #username='ngModel' minlength='8'> <div *ngIf='username.error?.minlength && username.touched' class='error'> The minlength is 8. </div> </form>
5.驗證狀態相關 [touched/valid/invalid/pristine/dirty/untouched等]
valid:控件有效
invalid:控件無效
pristine:控件值未改變
dirty:控件值已改變
untouched:表單控件未被訪問過
<form novalidate #f='ngForm'>
...
<button type='submit'
[disabled]='f.invalid'
(click)='onSubmit(f)'>
submit
</button>
</form>
二:Reactive Forms (Model-Driven Forms) - 響應式表單 [引入ReactiveFormsModule]
1.FormGroup(FormControl+FormArray)[表單對象]
FormGroup:包含一組FormControl和FormArray的實例,可用於跟蹤一組實例的值和驗證狀態
FormControl & FormArray:為單個表單控件提供支持的類,用於跟蹤控件的值和驗證狀態 前者是單值類型,后者是多值類型
<form novalidate [formGroup]='thatForm'>
<input type='text' formControlName='name'>
</form>
2.Validators [表單驗證]
//html方面
<form novalidate [formGroup]='thatForm'> <input type='text' formControlName='name'> <div class='error' *ngIf="thatForm.get('name').hasError('required') && thatForm.get('name').touched"> Name is required </div> <div class='error' *ngIf="thatForm.get('name').hasError('minlength') && thatForm.get('name').touched"> The minlength is 2. </div> </form>
//xx.component.ts export class xxComponent implements OnInit{ thatForm: FormGroup; constructor(){}; ngOnInit() { this.thatForm=new FormGroup({ name:new FormGroup('',[Validators.required,Validators.minLength(2)]) }) } }
3.FormBuilder [簡化新建FormGroup對象整個過程]
//FormGroup用法 export class xxComponent implements OnInit{ thatForm: FormGroup; constructor(){}; ngOnInit() { this.thatForm=new FormGroup({ name:new FormGroup('',[Validators.required,Validators.minLength(2)]) }) } }
//FormBuilder用法 export class xxComponent implements OnInit{ thatForm: FormGroup; constructor(private formBuilder: FormBuilder){}; ngOnInit() { this.thatForm=this.formBuilder.group({ name:['',[Validator.required,Validators.minLength(2)]] }) } }
4.FormValidation [統一管理驗證錯誤]
//html方面 <form novalidate [formGroup]='thatForm'> <input type='text' formControlName='name'> <div class='error'> {{formValidation.msgs.name.errors}} </div> </form>
//form-validation.ts export class xxValidation extends FormValidation{ constructor(){ super() } msgs={ name:{ errors:'', messages:{ required:'please type the name.', minlength:'please enter 3 charactors atleast.' } } } }
//xx.component.ts export class xxComponent implements OnInit{ formValidation:xxValidation=new xxValidation(); thatForm:FormGroup; constructor(private formBuilder: FormBuilder){} ngOnInit(){ this.thatForm=this.formBuilder.group({ name:['',[Validators.required,Validators.minLength(4)]] }) } }
兩種方式的比較:
模板驅動表單(Template-Driven Forms)
1.使用方便
2.適用於簡單的場景
3.通過[(ngModel)]實現數據雙向綁定
4.最小化組件類的代碼
5.不利於單元測試
響應式表單(Reactive Forms)
1.比較靈活
2.適用於復雜的場景
3.簡化了HTML模板的代碼,把驗證邏輯抽離出來了
4.方便跟蹤表單控件值的變化
5.易於單元測試